我有这样的代码红宝石注入创建阵列
notebooks.inject([]) do |res, nb|
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
end
第一nb
具有相匹配的条件和res
看起来像这样
["xxx1234"]
第二nb
不符合条件,然后删除/清除res
nil
从我的理解,第一个值应该保留在数组中。
我也将此分配给一个变量,并希望它是一个班轮。
我有这样的代码红宝石注入创建阵列
notebooks.inject([]) do |res, nb|
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
end
第一nb
具有相匹配的条件和res
看起来像这样
["xxx1234"]
第二nb
不符合条件,然后删除/清除res
nil
从我的理解,第一个值应该保留在数组中。
我也将此分配给一个变量,并希望它是一个班轮。
inject
工作从你如何想象有点不同。它只是返回循环的最后一个返回值,因为它循环遍历每个项目。一个简单的方法来解决这个是:
notebooks.inject([]) do |res, nb|
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
res # Returns the res array
end
这就是说,你应该使用select
您的使用情况下,你似乎只是过滤下来,其设置的笔记本电脑你想..这就是:
notebooks.select{|nb| Recipe::NOTEBOOKS.include?(nb.name)}.map(&:guid)
一般来说,我用inject
当我需要在一组项目上运行数学。例如
[1,2,3,4].inject(0) {|res, x| x * 2 + res}
累加器必须在每个循环迭代返回:
notebooks.inject([]) do |res, nb|
Recipe::NOTEBOOKS.include?(nb.name) ? res << nb.guid : res
end
事实上,在以后每次循环迭代,传递给res
块参数累加器是正是从以前的迭代返回。不执行
在你的榜样,在第二次迭代if
回报false
和
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
线在所有。也就是说,在第二次迭代之后,累加器会获得一个全新的值,这显然是nil
。
如果你打开两个循环,但更清洁,还是一个班轮:
notebooks.select { |nb| Recipe::NOTEBOOKS.include?(nb.name) }.map(&:guid)
+1正是我在想什么。这也有助于可读性,因为您将问题分为两个不同的步骤。尽管如此,我至少将它分成两行。 – Kelvin