Comment mapper avec index en Ruby?

Quelle est la manière la plus simple de convertir

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

à

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

Si vous utilisez ruby ​​1.8.7 ou 1.9, vous pouvez utiliser le fait que les méthodes itératives telles que each_with_index , lorsqu’elles sont appelées sans bloc, renvoient un object Enumerator , que vous pouvez appeler des méthodes Enumerable telles que map on. Donc, vous pouvez faire:

 arr.each_with_index.map { |x,i| [x, i+2] } 

Dans 1.8.6 vous pouvez faire:

 require 'enumerator' arr.enum_for(:each_with_index).map { |x,i| [x, i+2] } 

Ruby a Enumerator # with_index (offset = 0) . Pour convertir le tableau en un énumérateur, utilisez Object # to_enum ou Array # map , tout ce qui vous semble plus déclaratif:

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

Dans Ruby 1.9.3, il existe une méthode with_index appelée with_index qui peut être chaînée pour mapper.

Par exemple: array.map.with_index { |item, index| ... } array.map.with_index { |item, index| ... }

Sur le haut de la page

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

Voici deux autres options pour 1.8.6 (ou 1.9) sans utiliser énumérateur:

 # 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]] 

J’ai toujours apprécié la syntaxe de ce style:

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

En invoquant each_with_index vous obtenez un énumérateur que vous pouvez facilement mapper avec votre index disponible.

 a = [1, 2, 3] p [a, (2...a.size+2).to_a].transpose 
 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]] 

Je le fais souvent:

 arr = ["a", "b", "c"] (0...arr.length).map do |int| [arr[int], int + 2] end #=> [["a", 2], ["b", 3], ["c", 4]] 

Au lieu d’itérer directement sur les éléments du tableau, vous parcourez une série d’entiers et les utilisez comme index pour récupérer les éléments du tableau.

Un moyen amusant mais inutile de le faire:

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