'How to map/collect with index in Ruby?

What is the easiest way to convert

[x1, x2, x3, ... , xN]

to

[[x1, 2], [x2, 3], [x3, 4], ... , [xN, N+1]]


Solution 1:[1]

Ruby has Enumerator#with_index(offset = 0), so first convert the array to an enumerator using Object#to_enum or Array#map:

[:a, :b, :c].map.with_index(2).to_a
#=> [[:a, 2], [:b, 3], [:c, 4]]

Solution 2:[2]

In ruby 1.9.3 there is a chainable method called with_index which can be chained to map.

For example:

array.map.with_index { |item, index| ... }

Solution 3:[3]

Over the top obfuscation:

arr = ('a'..'g').to_a
indexes = arr.each_index.map(&2.method(:+))
arr.zip(indexes)

Solution 4:[4]

I have always enjoyed the syntax of this style:

a = [1, 2, 3, 4]
a.each_with_index.map { |el, index| el + index }
# => [1, 3, 5, 7]

Invoking each_with_index gets you an enumerator you can easily map over with your index available.

Solution 5:[5]

Here are two more options for 1.8.6 (or 1.9) without using enumerator:

# Fun with functional
arr = ('a'..'g').to_a
arr.zip( (2..(arr.length+2)).to_a )
#=> [["a", 2], ["b", 3], ["c", 4], ["d", 5], ["e", 6], ["f", 7], ["g", 8]]

# The simplest
n = 1
arr.map{ |c| [c, n+=1 ] }
#=> [["a", 2], ["b", 3], ["c", 4], ["d", 5], ["e", 6], ["f", 7], ["g", 8]]

Solution 6:[6]

A fun, but useless way to do this:

az  = ('a'..'z').to_a
azz = az.map{|e| [e, az.index(e)+2]}

Solution 7:[7]

a = [1, 2, 3]
p [a, (2...a.size+2).to_a].transpose

Solution 8:[8]

module Enumerable
  def map_with_index(&block)
    i = 0
    self.map { |val|
      val = block.call(val, i)
      i += 1
      val
    }
  end
end

["foo", "bar"].map_with_index {|item, index| [item, index] } => [["foo", 0], ["bar", 1]]

Solution 9:[9]

I often do this:

arr = ["a", "b", "c"]

(0...arr.length).map do |int|
  [arr[int], int + 2]
end

#=> [["a", 2], ["b", 3], ["c", 4]]

Instead of directly iterating over the elements of the array, you're iterating over a range of integers and using them as the indices to retrieve the elements of the array.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 aristotll
Solution 3 Andrew Grimm
Solution 4 yburyug
Solution 5 Phrogz
Solution 6 Automatico
Solution 7 Nikolay Bobrovskiy
Solution 8 Mo Wad
Solution 9 grandinero