For example, to return the 10,000th prime number I could write:
require \'prime\'
Prime.first(10000).last #=> 104729
But creating a huge
Based on sawa's solution, here's a more succinct alternative:
Prime.find.with_index(1) { |_, i| i == 10000 }
#=> 104729
or
Prime.find.with_index { |_, i| i == 9999 }
#=> 104723
The closest thing I can think of to a hypothetical at
method is drop
, which skips the indicated number of elements. It tries to return an actual array though so you need to combine it with lazy if you are using with infinite sequences, e.g.
Prime.lazy.drop(9999).first
What about this?
Prime.to_enum.with_index(1){|e, i| break e if i == 10000}
# => 104729
For enumerators that are not lazy, you probably want to put lazy
on the enumerator.
module Enumerable
def at(n)
enum = is_a?(Enumerator) ? self : each
(n-1).times { enum.next }
enum.next
end
end
(0..4).at(3)
#=> 2
{ a:1, b:2, c:3, d:4, e:5 }.at(3)
#=> [:c, 3]
'0ab_1ab_2ab_3ab_4ab'.gsub(/.(?=ab)/).at(3)
#=> "2"
require 'prime'; Prime.at(10000)
#=> 104729
e = 1.step; e.at(10)
#=> 10
[0,1,2,3,4].at(6)
#=> nil
'0ab_1ab_2ab_3ab_4ab'.gsub(/.(?=ab)/).at(6)
#=> StopIteration (iteration reached an end)
Note that '0ab_1ab_2ab_3ab_4ab'.gsub(/.(?=ab)/).class #=> Enumerator
.
Some refinements would be needed, such as checking that n
is an integer greater than zero and improving the exception handling, such as dealing with the case when self
is not an enumerator but has no method each
.