我有一个注入电话
[2,4,6].inject(true) { |res, val| res && val % 2 == 0 }
并希望将&&
运算符发送到inject(0, :+)
进行注入。我怎么能这样做?
答案 0 :(得分:12)
你不能因为&&
和||
与其他运算符不同,不是方法的合成糖(即没有方法称为&&
或||
),所以你不能用符号来引用它们。
但是,您可以避免使用inject
来计算布尔值数组的逻辑连接或分离,分别用all?
或any?
替换它,因为对于任何数组,以下条件持有:
ary.inject(true) { |res, b| res && b } == ary.all?
ary.inject(false) { |res, b| res || b } == ary.any?
因此,例如,您发布的代码可以重写为:
[2,4,6].map(&:even?).all?
# => true
更新:显然我的后一个示例不是表达此计算的正确方法,falsetru的答案要快得多:
require 'fruity'
compare(
-> { (0..1000).map(&:even?).all? },
-> { (0..1000).all?(&:even?) }
)
Running each test 1024 times. Test will take about 2 seconds.
Code 2 is faster than Code 1 by 111x ± 10.0
答案 1 :(得分:8)
如何使用Enumerable#all?
[2,4,6].all? &:even?
# => true
[2,4,6,5].all? &:even?
# => false
如果要使用inject
,则需要定义实例方法。
class Object
def is_even(val)
self && val % 2 == 0
end
end
[2,4,6].inject(true, :is_even) # => true
[1,2,4,6,5].inject(true, :is_even) # => false
答案 2 :(得分:3)
'&安培;&安培;'不是一种方法,因此你不能注入它。但是你可以注射&方法
[2,4,6,5].map(&:even?).inject(true, :&)
哪个会做同样的
注意:但是不应该这样做,因为它非常危险并且可能导致意外后果(如果在包含至少一个非布尔值(true,false,nil)的集合上运行)。您应该始终使用any?
或all?
方法。
答案 3 :(得分:0)
inject(0, :+)
会添加数组的所有元素,无论元素的内容是什么(奇数,偶数等)。
如果你想要inject(true, &:&&)
(我知道这不起作用),你的数组应该是一个布尔值的数组,以使你的问题有意义,这与:[true, false].all?
相同
重要:强> 你无法通过块arg和实际块,这意味着你无法检查它是否注入了&&在同一时间。
如果你坚持,试试这个:
[2,4,6].inject(true, & lambda { |x,y| x && y })
=> 6
这相当于你所要求的(我仍然不完全理解)