我有这段代码
notebooks.inject([]) do |res, nb|
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
end
第一个nb
符合条件,res
看起来像这个
["xxx1234"]
第二个nb
与删除/清除 res
nil
根据我的理解,第一个值应保留在数组中。
我也将它分配给一个变量,并希望它是一个单行。
答案 0 :(得分:4)
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
。 e.g。
[1,2,3,4].inject(0) {|res, x| x * 2 + res}
答案 1 :(得分:1)
如果您打开两个循环,但更清洁,仍然是单行:
notebooks.select { |nb| Recipe::NOTEBOOKS.include?(nb.name) }.map(&:guid)
答案 2 :(得分:0)
必须在每次循环迭代时返回累加器:
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
。