Using Ruby I want to evaluate all items in an array, and return true if they all pass a conditional test.
I can do this using e.g. array.all? { |value| value == 2 }
So:
> array=[2,2] > array.all? { |value| value == 2 } => true > array=[2,3] > array.all? { |value| value == 2 } => false
Great!
But, why does an empty array pass this test?
> array=[] > array.all? { |value| value == 2 } => true
Shouldn't this return false?
And if I need it to return false, how should I modify the method?
Because Array is type of object , the fact that an empty Array is conversed to true is correct.
Empty arrays are true but they're also equal to false.
If the length of the object is 0, then the array is considered to be empty and the function will return TRUE. Else the array is not empty and the function will return False.
arrays are objects, objects are truthy. just ask for array. length, if not zero, it will be truthy. when you explicitly convert to Boolean, the array turns into an empty string first, then the empty string turns into false.
This is a vacuous truth. It's the standard interpretation of a universal quantification, i.e. a
collection.all? { |x| some_predicate(x) }
over an empty collection
, but it's known to strike people as counter-intuitive when they first see it in a formal setting. One nice way to think about why this is the preferred semantics is to think about how you would implement all?
.
To make your test require that the array is non-empty, just do
array.any? && array.all? { |x| x == 2 }
Note that array.any?
is fast no matter how large the array, whereas array.all? { |x| x == 2 }
can be slow, depending on how big array
is and how rare 2
is in it. So put the array.any?
first.
Also note, there are degenerate cases where this won't work, for instance if array
is [nil]
or [false]
. If cases like this might come up, replace array.any?
with array.any? { true }
.
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