I'm using Ruby 2.4. Let's say I have an array of MyData instances. Each object has an attribute attr1. Given my array
array = [myobj1, myobj2, myobj3]
How do I check that every object in the array contains a nil value for attr1?
Try something like this
my_arr.all? { |my_obj| my_obj.attr1.nil? }
How do I check that every object in the array contains a
nilvalue forattr1?
array
.map(&:attr1) # maps by attr1
.compact # removes nil values from collection
.empty? # checks, whether array is empty
false and nil values.The method returns
trueif the block never returnstruefor all elements. If the block is not given,none?will returntrueonly if none of the collection members istrue.
It can be shortened to just
array.map(&:attr1).none?
Or even shorter (I bet this is the shortest one possible :D (without crazy metaprogramming))
array.none?(&:attr1)
which basically checks, whether none of the object.attr1 is truthy.
array.map(&:attr1).all?(&:itself)?nil and false, thoughThe simplest thing is to use none? when you want to know if all values are nil:
[nil, nil].none? # => true
[true, nil].none? # => false
Or you can use any? and toggle the boolean result:
![nil, nil].any? # => true
![true, nil].any? # => false
Extending that to fit your object:
class MyData
def initialize(b)
@attr1 = b
end
def attr1
@attr1
end
end
obj1 = MyData.new(nil)
obj2 = MyData.new(true)
[obj1, obj1].none?(&:attr1) # => true
[obj1, obj2].none?(&:attr1) # => false
This will break down if you can have false values and want to consider them different than nil because none? considers nil and false values the same:
[false].none? # => true
(any? and all? also get fooled by the truthiness of a value.)
To work around that I'd add a method to the class that tests whether that attribute is actually nil:
def nil?
@attr1.nil?
end
Then something using all? works:
obj3 = MyData.new(false)
[obj1, obj1].all?(&:nil?) # => true
[obj1, obj2].all?(&:nil?) # => false
[obj1, obj2, obj3].all?(&:nil?) # => false
nilatt1's?