2010-10-22 171 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