2015-04-06 62 views
2

Ruby的新功能;當我使用數組時,Enumerable#each_with_indexArray#index之間有什麼區別我一直在處理一個多維數組,我試圖找到給定值的位置。當我使用任何一個時,我的代碼都能夠通過所有的測試。座標是我用來保存給定值的位置的數組(在本例中爲1)Ruby中的each_with_index與index索引的用例

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 

在此先感謝您的幫助。

回答

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被傳遞到塊,這將調用Array#each因爲接收器,field是類Array的一個實例。

我們可以通過將其轉換到陣列看到的enum的元素:

enum.to_a 
    #=> [[[1, 0], 0], [[0, 0], 1]] 

正如所看到的,它有兩個元件,兩個元件的每一個是一個陣列,第一個是兩個整數的數組第二個是整數。

我們可以通過發送Enumerator#nextenum和分配塊變量由next返回的值模擬each操作。由於只有一個塊變量,item,我們有:

item = enum.next 
    #=> [[1, 0], 0] 

這很可能既不是你所期待也沒有人知道你想要的。

接下來,你item調用Array#index

item.index(1) 
    #=> nil 

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 

我會讓你把它從這裏開始,但讓我再提一下NG。我不主張,但你可以寫:

在這種情況下
field.each_with_index do |(first, second), index|... 

(first, second), index = enum.next 
     #=> [[1, 0], 0] 
first #=> 1 
second #=> 0 
index #=> 0 
+1

++也許您的下一個答案可以包含一些牙線清單示例**^,,,^** – naomik 2015-04-06 04:28:08

1

見紅寶石DOC:http://ruby-doc.org/core-2.2.0/Array.html#method-i-indexhttp://ruby-doc.org/core-2.2.1/Enumerable.html#method-i-each_with_index

indexArray的方法,它會檢測是否存在於特定Array一個項目,如果該項目存在返回的索引,並且如果nil不存在。

each_with_index是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

1

Array#indexEnumerable#each_with_index沒有任何關係(從功能上講),一個用於獲取數組中的對象的索引,另一個用於遍歷集合。

實際上each_with_indexeach方法的變異,它另外產生了集合中實際對象的索引。如果您需要跟蹤您所處對象的當前位置,則此方法非常有用。它可以節省創建和增加附加變量的麻煩。

例如

['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_indexindex

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

鑑於:

fields = [[1, 0], [0, 0]] 

可枚舉#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