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
提前感谢您的帮助。
答案 0 :(得分: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
让:
enum = field.each_with_index
#=> #<Enumerator: [[1, 0], [0, 0]]:each_with_index>
如您所见,这将返回一个枚举器。
Ruby看到你的代码如下:
enum.each do |item|
if item.index(1)
coordinates.push(field.index(item)).push(item.index(1))
end
end
枚举器的元素将由Enumerator#each传递到块中,由于接收者field
是类Array
的实例,因此将调用Array#each。
我们可以通过将enum
转换为数组来查看enum.to_a
#=> [[[1, 0], 0], [[0, 0], 1]]
的元素:
each
如你所见,它有两个元素,每个元素都是两个元素的数组,第一个是两个整数的数组,第二个是整数。
我们可以通过向enum
发送Enumerator#next并将块变量分配给next
返回的值来模拟item
的操作。由于只有一个块变量item = enum.next
#=> [[1, 0], 0]
,我们有:
item
这很可能既不是你期望的也不是你想要的。
接下来,您在item.index(1)
#=> nil
上调用Array#index:
index
item
在数组1
中搜索等于item.index(0) #=> 1
的元素。如果找到一个,则返回该数组中该元素的索引。 (例如,[1,0]
)。由于0
和1
都不等于index
,nil
会返回field.each_with_index do |item, index|...
。
让我们回放(并重新创建枚举器)。您需要两个块变量:
enum.each do |item, index|...
与:
相同item, index = enum.next
#=> [[1, 0], 0]
item #=> [1, 0]
index #=> 0
现在:
item.index(1)
#=> 0
和
field.each_with_index do |(first, second), index|...
我会让你从这里拿走它,但让我再说一件事。我不是在提倡它,但你可以写:
(first, second), index = enum.next
#=> [[1, 0], 0]
first #=> 1
second #=> 0
index #=> 0
在这种情况下:
{{1}}
答案 1 :(得分:1)
请参阅Ruby doc:http://ruby-doc.org/core-2.2.0/Array.html#method-i-index和http://ruby-doc.org/core-2.2.1/Enumerable.html#method-i-each_with_index
index
是Array
的一种方法,它会检测项目是否存在于特定Array
中,如果项目存在则返回索引,nil
如果不存在则返回存在。
each_with_index
是Enumerable
mixin的方法,通常需要2个参数,第一个是item,第二个是index。
因此,您的样本可以简化为:
field = [[1, 0], [0, 0]]
coordinates = []
field.each_with_index do |item, index|
item_index = item.index(1)
coordinates << index << item_index if item_index
end
puts coordinates.inspect # => [0, 0]
请注意,field.index(item)
只是index
。
答案 2 :(得分:1)
Array#index
和Enumerable#each_with_index
无关联(从功能上讲),一个用于获取数组中对象的索引,另一个用于遍历集合。
实际上each_with_index
是each
方法的变异,它还会产生集合中实际对象的索引。如果您需要跟踪所在对象的当前位置,此方法非常有用。它可以省去创建和增加其他变量的麻烦。
例如
['a', 'b', 'c', 'd'].each_with_index do|char, idx|
puts "#{idx}) #{char}"
end
输出:
0) a
1) b
2) c
3) d
没有each_with_index
idx = 0
['a', 'b', 'c', 'd'].each do|char|
puts "#{idx}) #{char}"
idx += 1
end
输出:
0) a
1) b
2) c
3) d
要在多维数组中查找对象的索引,您必须至少迭代矩阵的所有行,如下所示(使用each_with_index
和index
)
def find_position(matrix, obj)
matrix.each_with_index do|row, i|
return [i, j] if j = row.index(obj)
end
return nil
end
例如:
find_position([[2,3],[4,5]], 5) # => [1, 1]
答案 3 :(得分:1)
鉴于:
fields = [[1, 0], [0, 0]]
Enumerable#each_with_index将每个索引以及每个对象传递给块:
fields.each_with_index do |field, idx|
puts "#{field}, #{idx}"
end
#=> [1, 0], 0
#=> [0, 0], 1
Array#index返回匹配数组元素的索引:
puts fields.index([1, 0])
#=> 0