Ruby中使用each_with_index与index的用例

GN*_*GNS 2 ruby arrays

Ruby的新手; 当我使用数组时,是否存在差异Enumerable#each_with_index,Array#index我一直在使用多维数组,我试图找到给定值的位置.当我使用其中任何一个时,我的代码都能够通过所有测试.坐标是我用来保存给定值的位置的数组(在本例中为1)

field=[[1,0],[0,0]]
coordinates=[]  
field.each_with_index do |item|
  if item.index(1)
    coordinates.push(field.index(item)).push(item.index(1))
  end
end
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助.

Car*_*and 5

让我们仔细看看你的代码:

field=[[1,0],[0,0]]
coordindates = []  
field.each_with_index do |item|
  if item.index(1)
    coordinates.push(field.index(item)).push(item.index(1))
  end
end
Run Code Online (Sandbox Code Playgroud)

让:

enum = field.each_with_index
  #=> #<Enumerator: [[1, 0], [0, 0]]:each_with_index>
Run Code Online (Sandbox Code Playgroud)

如您所见,这会返回一个枚举器.

Ruby看到你的代码是这样的:

enum.each do |item|
  if item.index(1)
    coordinates.push(field.index(item)).push(item.index(1))
  end
end
Run Code Online (Sandbox Code Playgroud)

枚举器的元素将由Enumerator#each传递到块中,它们将调用Array#,因为接收器field是类的实例Array.

我们可以enum通过将其转换为数组来查看元素:

enum.to_a
  #=> [[[1, 0], 0], [[0, 0], 1]]
Run Code Online (Sandbox Code Playgroud)

如您所见,它有两个元素,每个元素都是两个元素的数组,第一个是两个整数的数组,第二个是整数.

我们可以模拟的操作each通过发送枚举#旁边来enum和分配块变量返回的值next.由于只有一个块变量item,我们有:

item = enum.next
  #=> [[1, 0], 0]
Run Code Online (Sandbox Code Playgroud)

这很可能既不是你期望的,也不是你想要的.

接下来,您调用数组#指数上item:

item.index(1)
  #=> nil
Run Code Online (Sandbox Code Playgroud)

index在数组中搜索item等于的元素1.如果找到一个,则返回该数组中该元素的索引.(例如,item.index(0) #=> 1).既不是[1,0]也不0等于1,index返回nil.

让我们回放(并重新创建枚举器).你需要两个块变量:

field.each_with_index do |item, index|...
Run Code Online (Sandbox Code Playgroud)

这与:

enum.each do |item, index|...
Run Code Online (Sandbox Code Playgroud)

所以现在:

item, index = enum.next
      #=> [[1, 0], 0] 
item  #=> [1, 0] 
index #=> 0 
Run Code Online (Sandbox Code Playgroud)

和

item.index(1)
  #=> 0
Run Code Online (Sandbox Code Playgroud)

我会让你从这里拿走它,但让我再说一件事.我不是在鼓吹它,但你可以写:

field.each_with_index do |(first, second), index|...
Run Code Online (Sandbox Code Playgroud)

在这种情况下:

(first, second), index = enum.next
       #=> [[1, 0], 0] 
first  #=> 1
second #=> 0 
index  #=> 0
Run Code Online (Sandbox Code Playgroud)