How to Get the Nth Element of an Enumerable in Ruby

How to get the nth element of an Enumerable in Ruby

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

Ruby get nth item from massive range

Enumerate only up to n,

or

Develop a function that given a number n, f(n) gives you the nth item of your range of possible solutions.

In your case you may treat your range as a number system with base 26. Rebasing a number is a well known problem. There's an example on my site to go from a base-10 number to a base-26 number (represented by the alphabet) even in ruby (made by a colleague of mine). Some variation of this algorithm would probably also work for you.

Update
Maybe it didn't sink in that this is your answer :D

Here's the ruby code to get the nth item of your range:

def rbase(value)
a = ('a'..'z')
b = a.to_a
base = b.length
text = []
begin
value, rest = value.divmod(base)
text << b[rest]
end until value.zero?
text.reverse.join
end

then you can use it like that.

irb(main):030:0> rbase(789).rjust(10,'a')
=> "aaaaaaabej"

How do you select every nth item in an array?

You could also use step:

n = 2
a = ["cat", "dog", "mouse", "tiger"]
b = (n - 1).step(a.size - 1, n).map { |i| a[i] }

Iterate over n to last item in a Ruby enumerable

Ruby has a cool way of doing this with the splat operator *. Here is an example:

a = [1,2,3,4]
first, *rest = *a
puts first # 1
puts rest # [2,3,4]
puts a # [1,2,3,4]

Here is your code rewritten:

first, *rest = @model.children
puts first.full_name
rest.each do |child|
puts child.short_name
end

I hope this helps!

In Ruby, what does it mean to return an 'enumerable'

An Enumerator abstracts the idea of enumeration so that you can use all of the handy Enumerable methods without caring what the underlying data structure is.

For example, you can use an enumerator to make an object that acts kind of like an infinite array:

squares = Enumerator.new do |yielder|
x = 1
loop do
yielder << x ** 2
x += 1
end
end

squares.take(10)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
squares.count
# don't wait up for this one!

The cool thing about enumerators is that they are enumerable themselves and most Enumerable methods return enumerators if you don't give them a block. This is what allows you to chain method calls to get one big enumerator.

Here's how I would code each_with_index so that it can be chained nicely:

class Array
def my_each_with_index &blk
e = Enumerator.new do |yielder|
i = 0
each do |x|
yielder << [x, i]
i += 1
end
end

return e unless blk
e.each(&blk)
end
end

[3,2,1].my_each_with_index { |x, i| puts "#{i}: #{x}" }
# 0: 3
# 1: 2
# 3: 1

So first we create an enumerator which describes how to enumerate with indices. If no block is given, we simply return the enumerator. Otherwise we tell the enumerator to enumerate (which is what each does) using the block.

Get every n-elements of array

Enumerable#each_slice

Iterates the given block for each
slice of elements. If no block is
given, returns an enumerator.

e.g.:

(1..10).each_slice(3) {|a| p a}
# outputs below
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10]

Use as:

irb(main):002:0> a =  Array(1..33)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
irb(main):003:0> a.each_slice(5) # no good
=> #<Enumerable::Enumerator:0x47ae6e8>
irb(main):004:0> a.each_slice(5).to_a # good
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33]]

What's the fastest way in Ruby to get the first enumerable element for which a block returns true?

Several core ruby classes, including Array and Hash include the Enumerable module which provides many useful methods to work with these enumerations.

This module provides the find or detect methods which do exactly what you want to achieve:

arr = [12, 88, 107, 500]
arr.find { |num| num > 100 } # => 107

Both method names are synonyms to each other and do exactly the same.

Ruby enumerable - find up to n occurrences of matching element

Use a lazy enumerator with Enumerable#lazy:

arr.lazy.select(&:odd?).take(3).force
# => [1, 3, 5]

force is used to force the lazy enumerator to evaluate. Or, you could use first as it's eager:

arr.lazy.select(&:odd?).first(3)
# => [1, 3, 5]

How to iterate over all but first element of an enumerable

How about this?

[1,2,3].drop(1).each {|x| puts x }
# >> 2
# >> 3

Here's how you can continue walking the iterator

a = [1,2,3]

b = a.each # => #<Enumerator: [1, 2, 3]:each>
b.next # skip first one

loop do
c = b.next
puts c
end
# >> 2
# >> 3


Related Topics



Leave a reply



Submit