2010-08-26 71 views
105

更多的語法好奇心,而不是問題解決...什麼是'Ruby的方式'一次迭代兩個陣列

我有兩個等長的數組,並且希望一次迭代它們 - 例如,在特定索引處輸出它們的值。

@budget = [ 100, 150, 25, 105 ] 
@actual = [ 120, 100, 50, 100 ] 

我知道,我可以使用each_index和索引到數組,像這樣:

@budget.each_index do |i| 
    puts @budget[i] 
    puts @actual[i] 
end 

是否有Ruby的方式做到這一點更好?東西這個?

# Obviously doesn't achieve what I want it to - but is there something like this? 
[@budget, @actual].each do |budget, actual| 
    puts budget 
    puts actual 
end 
+1

都是相同大小的數組? – Anurag 2010-08-26 22:27:33

+1

是的 - 都知道長度相同 – nfm 2010-08-26 22:32:56

回答

241
>> @budget = [ 100, 150, 25, 105 ] 
=> [100, 150, 25, 105] 
>> @actual = [ 120, 100, 50, 100 ] 
=> [120, 100, 50, 100] 

>> @budget.zip @actual 
=> [[100, 120], [150, 100], [25, 50], [105, 100]] 

>> @budget.zip(@actual).each do |budget, actual| 
?> puts budget 
>> puts actual 
>> end 
100 
120 
150 
100 
25 
50 
105 
100 
=> [[100, 120], [150, 100], [25, 50], [105, 100]] 
+12

'.each'能展開數組元素嗎?我想知道還有多少Ruby我不知道:/ – 2010-08-26 22:35:48

+1

我愛Ruby!:) – nfm 2010-08-26 22:42:26

+5

如果你打算使用這樣的表達式,最好在方法調用中使用括號,以防萬一。 @ budget.zip(@actual).each – AboutRuby 2010-08-26 22:48:47

21

使用Array.zip方法並將其傳遞給一個塊,以順序遍歷相應的元素。

+0

完美,簡單高效 – akostadinov 2015-07-30 20:48:25

16

除了a.zip(b).each{|x,y| }如其他人所說的,你也可以說[a,b].transpose.each{|x,y| },這令我更對稱的一點點。雖然可能沒有那麼快,因爲您正在創建額外的[a,b]陣列。

+11

+1「轉置」的好處之一就是如果兩個數組長度不一樣,會引發異常。 – 2013-01-13 21:56:22

18

還有另一種方法來遍歷兩個陣列在一次使用枚舉:

2.1.2 :003 > enum = [1,2,4].each 
=> #<Enumerator: [1, 2, 4]:each> 
2.1.2 :004 > enum2 = [5,6,7].each 
=> #<Enumerator: [5, 6, 7]:each> 
2.1.2 :005 > loop do 
2.1.2 :006 >  a1,a2=enum.next,enum2.next 
2.1.2 :007?> puts "array 1 #{a1} array 2 #{a2}" 
2.1.2 :008?> end 
array 1 1 array 2 5 
array 1 2 array 2 6 
array 1 4 array 2 7 

枚舉比上面使用的實施例更強大,因爲他們允許無限的串聯,並聯迭代中,其它技術。

13

相關原來的問題,用於遍歷你想要的值週期不等長度的陣列周圍,你可以使用

[1,2,3,4,5,6].zip([7,8,9].cycle) 

和紅寶石會給你

[[1, 7], [2, 8], [3, 9], [4, 7], [5, 8], [6, 9]] 

這將您從nil值中省去,只需使用zip即可獲得

+1

不錯的紅寶石珍聞。 – alistairholt 2016-01-19 16:39:02

+1

這就是我一直在尋找的,謝謝! – Malachi 2016-07-19 13:32:47

5

只需將兩個值如果你正在處理數組,數組一起工作的很好。但是,如果你正在處理永無止境的統計員,比如像這些是什麼:

enum1 = (1..5).cycle 
enum2 = (10..12).cycle 

enum1.zip(enum2)失敗,因爲zip試圖評估所有元素,並結合他們。相反,這樣做:

enum1.lazy.zip(enum2) 

那一個lazy通過使所產生的枚舉懶惰評估爲您節省。

1

如何妥協,並使用#each_with_index?

include Enumerable 

@budget = [ 100, 150, 25, 105 ] 
@actual = [ 120, 100, 50, 100 ] 

@budget.each_with_index { |val, i| puts val; puts @actual[i] }