如何在Ruby中使用索引进行映射?


Answers:


835

如果您使用的是ruby 1.8.7或1.9,则可以使用以下事实:each_with_index在没有块的情况下调用类似的迭代器方法时,会返回一个Enumerator对象,您可以Enumerablemap在on上那样调用方法。因此,您可以执行以下操作:

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

在1.8.6中,您可以执行以下操作:

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

谢谢!您能给我一个指向文档的指针.each_with_index.map吗?
Misha Moroshko 2011年

1
@Misha:mapEnumerable一如既往的方法。each_with_index中,当不使用块调用,返回一个Enumerator对象(在1.8.7+),其中混合料Enumerable,所以可以调用mapselectreject等等它就像上的阵列,散列,范围等
sepp2k

9
海事组织,这在1.8.7+中更简单易读:arr.map.with_index{ |o,i| [o,i+2] }
Phrogz 2011年

4
@Phrogz:map.with_index在1.8.7中不起作用(map在1.8中在没有块的情况下调用时返回一个数组)。
sepp2k 2011年

2
重要的是要注意,这不适用于.map!如果您想直接影响正在循环的数组。
Ash Blue


130

在ruby 1.9.3中,有一个可链接的方法称为with_index,可以链接到地图。

例如:

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

17

最重要的混淆:

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

12
安德鲁必须有很好的工作保障!:)
David J.

9

对于不使用枚举器的1.8.6(或1.9),这是另外两个选项:

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


4

一种有趣但无用的方法:

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

为什么讨厌?这是一种有效的方法,我什至说那是实现结果的愚蠢方法。
Automatico

对#index的调用意味着这现在是一个O(N ^ 2)循环,以及为什么+2吗?:)
rogerdpack

2
在我写的时候A fun, but useless way+2是要创建OP要求的输出
Automatico


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

3
我的天啊!你还读过其他答案吗?map.with_index在红宝石中已经存在。为什么建议重新打开可枚举的类并添加已经存在的类?
nathanvda 2014年

对于1.8.6和1.8.7(这是我们中的某些人仍在使用),这可能是一种更简单的方法,而不必使用诸如此类的古怪的东西each_with_index.map,即使我们这些人在较新的版本上也可能更喜欢使用它map.with_index FWIW :)
rogerdpack

1

我经常这样做:

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

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

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

而不是直接遍历数组的元素,而是遍历一系列整数并将其用作索引以检索数组的元素。


1
如果您阅读其他答案,希望您现在意识到有更好的方法。因此不确定是否需要添加它。
nathanvda 2014年

如果安德鲁·格林(Andrew Grimm)的答案应得10票,那么这一票至少应得1票!
卡米尔·古德塞内
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.