有人问:
我想获取前 10 个项目,然后离开“每个”循环。
使用throw 和catch 来完成此操作,只需对示例进行少量更改:
catch(:done) do
c = 0
collected = []
items.each do |item|
collected << item
throw(:done, collected) if c == 9 # started at 0
c += 1
end
collected # if the list is less than 10 long, return what was collected
end
只需将throw 标签:done 与collected 和正在等待:done 的catch 返回collected。
然后把它“红宝石”一下:
catch(:done) do
items.inject([]) do |collected, item|
throw(:done, collected) if collected.size == 10
collected << item # collected gets returned here and populates the first argument of this block
end
end
我不知道为什么有些人拒绝使用inject 而是使用reduce(它们是等效的),而显然给inject([]) 的空数组正在注入items!无论如何,如果少于 10 个项目,inject 将返回 collected。
大多数答案都试图回答问题的意图,而不是询问的内容,items.take(10) 在这种情况下确实很有意义。但我可以想象想要抢购符合我 100 美元预算的第一批物品。然后你可以简单地:
catch(:done) do
items.inject({items: [], budget: 100}) do |ledger, item|
remainder = ledger[:budget] - item.price
if remainder < 0
throw(:done, ledger)
else
ledger.tap do |this|
this[:items] << item
this[:budget] = remainder
end # tap just returns what is being tapped into, in this case, ledger
end
end
end