2010-10-22 107 views
72

如果我有作爲給。每次循環結束紅寶石

users.each do |u| 
    #some code 
end 

這樣一個循環,用戶是多個用戶的哈希值。什麼是最簡單的條件邏輯看,如果你是在用戶的散列的最後一個用戶,只希望爲最後一個用戶執行特定的代碼,以便像

users.each do |u| 
    #code for everyone 
    #conditional code for last user 
    #code for the last user 
    end 
end 

感謝

+0

你真的是指哈希?對散列進行排序並不總是可靠的(取決於你如何在散列中添加內容以及你使用的是什麼ruby版本)。由於訂單不可靠,「最後」項目將不一致。問題中的代碼和您得到的答案更適合於數組或枚舉。例如,哈希沒有'each_with_index'或'last'方法。 – Shadwell 2010-10-22 20:49:17

+1

'Hash'在Enumerable中混合,所以它確實有'each_with_index'。即使散列鍵沒有排序,這種邏輯總是在渲染視圖時出現,其中最後一項可能以不同的方式顯示,而不管它是否在任何有意義的數據上都是「最後」。 – Raphomet 2010-10-22 21:04:34

+0

當然,非常正確,哈希確實有'each_with_index',道歉。是的,我可以看到它會出現;只是試圖澄清這個問題。個人而言,對我來說最好的答案是使用'.last',但不適用於僅散列數組。 – Shadwell 2010-10-22 21:09:00

回答

119
users.each_with_index do |u, index| 
    # some code 
    if index == users.size - 1 
    # code for the last user 
    end 
end 
+1

問題與這是一個有條件的是每一次跑過。在循環外使用'.last'。 – bcackerman 2013-08-18 20:01:46

+1

我只是補充說,如果你正在迭代一個散列,你必須這樣寫: 'users.each_with_index do |(key,value),index | #你的代碼 結束# – HUB 2014-08-27 13:05:01

+0

我知道這不是完全相同的問題,但是這個代碼效果更好我認爲如果你想爲大家做點什麼,但是最後一個用戶,所以我upvoting,因爲這是我一直在尋找 – WhiteTiger 2015-12-11 23:19:31

8

你有沒有試過each_with_index

users.each_with_index do |u, i| 
    if users.size-1 == i 
    #code for last items 
    end 
end 
5
h = { :a => :aa, :b => :bb } 
h.each_with_index do |(k,v), i| 
    puts ' Put last element logic here' if i == h.size - 1 
end 
36

如果這是一個非此即彼/或情況,在那裏你將一些代碼,所有最後一個用戶,然後一些獨特的代碼最後一個用戶,另外的一個解決方案可能更合適。

但是,您似乎正在爲所有用戶運行相同的代碼,併爲最後一位用戶運行了一些附加代碼。如果是這樣的情況下,這似乎更正確,更明確指出你的意圖:

users.each do |u| 
    #code for everyone 
end 

users.last.do_stuff() # code for last user 
+2

+1不需要條件,如果這是適當的。 (當然,我在這裏) – Jeremy 2010-10-22 22:44:10

+0

@meagar會不會這個循環低谷用戶兩次? – ant 2015-09-16 16:00:30

+0

@ant不,有一個循環和一個與'.last'的調用,這與循環無關。 – meagar 2015-09-16 16:21:08

17

我認爲最好的辦法是:

users.each do |u| 
    #code for everyone 
    if u.equal?(users.last) 
    #code for the last user 
    end 
end 
+17

這個答案的問題是,如果最後一個用戶也出現在列表中較早的位置,那麼條件代碼將被多次調用。 – evanrmurphy 2012-12-11 05:07:37

+0

你必須使用'u.equal?(users.last)','equal?'方法比較object_id,而不是對象的值。但這不適用於符號和數字。 – 2016-01-30 10:50:06

0

有哈希紅寶石的某些版本沒有最後的方法

h = { :a => :aa, :b => :bb } 
last_key = h.keys.last 
h.each do |k,v| 
    puts "Put last key #{k} and last value #{v}" if last_key == k 
end 
+0

這是一個改善別人答案的答案嗎?請張貼哪個答案提到'最後'的方法,以及你打算如何解決這個問題。 – Artemix 2013-07-23 07:28:47

+0

對於沒有「last」的Ruby版本,這組密鑰將是無序的,所以這個答案無論如何都會返回錯誤/隨機結果。 – meagar 2014-01-15 17:32:17

0

另一個解決方案是從StopIteration異常營救:

user_list = users.each 

begin 
    while true do 
    user = user_list.next 
    user.do_something 
    end 
rescue StopIteration 
    user.do_something 
end 
+4

這不是一個很好的解決這個問題的方法。例外情況不應濫用於簡單的流量控制,它們適用於*特殊*情況。 – meagar 2014-01-15 17:24:51

+0

@meagar這實際上非常酷。我同意**不受約束的**例外情況或需要傳遞給更高方法的例外情況應僅適用於特殊情況。然而,這是一個簡單的(而且顯然是唯一的)方式,可以訪問ruby關於迭代器結束位置的原生知識。如果有另一種方式,當然是首選。 我唯一需要解決的問題是,它似乎跳過了第一項並且什麼都不做。解決這個問題將會讓它超越笨拙的邊界。 – Adamantish 2017-01-19 14:53:05

3

有時候我覺得把邏輯分成兩個部分比較好,一個是所有用戶,另一個是最後一個。所以我會做這樣的事情:

users[0...-1].each do |user| 
    method_for_all_users user 
end 

method_for_all_users users.last 
method_for_last_user users.last 
3

您可以使用@微薄的做法也是一個非此即彼/或情況,在那裏你將一些代碼,除了最後一個用戶,然後一些獨特的代碼,只最後的用戶。

users[0..-2].each do |u| 
    #code for everyone except the last one, if the array size is 1 it gets never executed 
end 

users.last.do_stuff() # code for last user 

這樣,你並不需要一個條件!

+0

@BeniBela不,[-1]是最後一個元素。沒有[-0]。所以倒數第二是[-2]。 – coderuby 2016-05-21 14:07:08

+0

'users [0 ..- 2]'是正確的,就像'users [0 ...- 1]'一樣。請注意不同的範圍運算符'..'和'...',請參閱http://stackoverflow.com/a/9690992/67834 – 2017-01-12 15:47:04