在循环中初始化变量

时间:2015-09-29 14:26:44

标签: ruby iterator

我定义一个包含空对象的变量,然后在each循环(或其他类型的循环)中将元素推入其中,如下所示:

foo = []
collection.each do |item|
  foo << item
end
foo

或者像这样:

foo = []
count = 0
collection.each do |item|
  count += 1
  raise ArgumentError if count > 10
  foo << item
end
foo

但是,foocount过于频繁出现并使代码混乱。有没有一种方法可以缩短这段代码?我想相信第一个foo可以放在循环中运行一次。

2 个答案:

答案 0 :(得分:5)

您可以使用inject方法:

foo = collection.inject([]) {|sum, item| sum << item }

single-line block只是一种Ruby风格,对于单行块,更喜欢{...}而不是do...end。无论是多行还是单行块,您也可以使用do...end,但对于多行块,do...end更好。

foo = collection.inject([]) do |sum, item| 
          sum << item
       end # This is ok, but `{...}` looks better.

多行:

foo = collection.inject([]) do |sum, item| 
          # line 1
          # line 2
          # and more
       end
  

对于Ruby风格,您可以从The Ruby Style Guide

获取更多信息

答案 1 :(得分:2)

我在这种情况下使用的替代方法是each_with_obejct

collection = ['string', 1, []]
foo =
  collection.each_with_object([]) do |item,array|
    array << item
  end
#=> ['string', 1, []]

同样,如果您需要索引,可以将each_with_indexeach_with_object链接起来,但它会变得稍微复杂一点:

collection = ['string', 1, []]

foo =
  collection.each_with_index.with_object([]) do |item_and_index,array|
    item, index = item_and_index
    raise ArgumentError if index > 10
    array << item
  end
#=> ['string', 1, []]

item_and_index成为一个数组,在0索引中保存集合中的项目,并在每次循环时成为1索引中项目的索引。