我定义一个包含空对象的变量,然后在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
但是,foo
或count
过于频繁出现并使代码混乱。有没有一种方法可以缩短这段代码?我想相信第一个foo
可以放在循环中运行一次。
答案 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_index
与each_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索引中项目的索引。