I have an inject call
[2,4,6].inject(true) { |res, val| res && val % 2 == 0 }
and want to send the &&
operator to inject as in inject(0, :+)
. How can I do that?
In C, the double ampersand && is a short-circuit logical AND operation. If you have something like a && b , then this will evaluate as follows: it will return true if both a and b are true, but if a is false then b will never be executed.
JavaScript uses the double ampersand ( && ) to represent the logical AND operator. The following expression uses the && operator: let result = a && b; Code language: JavaScript (javascript) If a can be converted to true , the && operator returns the b ; otherwise, it returns the a .
The single ampersand operator (&) evaluates both sides of the operator before arriving at its answer. The double ampersand operator (&& – also known as the conditional-AND operator) evaluates the RHS only if the LHS is true. It short-circuits the evaluation so it doesn't have to evaluate the RHS if it doesn't have to.
The & operator in Java has two definite functions: As a Relational Operator: & is used as a relational operator to check a conditional statement just like && operator. Both even give the same result, i.e. true if all conditions are true, false if any one condition is false.
You can't because &&
and ||
, unlike other operators, are not syntacic sugar for methods (i.e. there is no method called &&
or ||
), so you can't reference them using a symbol.
However you can avoid using inject
to compute the logical conjunction or disjunction of an array of boolean values, replacing it with all?
or any?
respectively, because for any array the following conditions hold:
ary.inject(true) { |res, b| res && b } == ary.all?
ary.inject(false) { |res, b| res || b } == ary.any?
So, for example, the code you posted could be rewritten as:
[2,4,6].map(&:even?).all?
# => true
Update: obviously my latter example is not the right way to express this computation, falsetru's answer is much faster:
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
How about using Enumerable#all?
[2,4,6].all? &:even?
# => true
[2,4,6,5].all? &:even?
# => false
If you want to use inject
, you need to define an instance method.
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
'&&' is not a method, hence you can't inject it. However you can inject & method.
[2,4,6,5].map(&:even?).inject(true, :&)
Which will do the same
NOTE: This however should not be done, as it is extremely risky and might cause unexpected consequences (if run on collection containing at least one non-boolean (true, false, nil) value). You should always use any?
or all?
methods instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With