注入双&符号运算符

时间:2014-02-05 15:01:33

标签: ruby

我有一个注入电话

[2,4,6].inject(true) { |res, val| res && val % 2 == 0 }

并希望将&&运算符发送到inject(0, :+)进行注入。我怎么能这样做?

4 个答案:

答案 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

这相当于你所要求的(我仍然不完全理解)