Reputation: 2615
I have an array of hashes like so
[ {a:nil,...}, {a:nil,...}, ... ]
I'd like to check to if the value for all elements or for a particular key in the hash array are nil.
I know you do this for a single hash like so
hash.values.include? nil
Is there a better way than having to iter through the array and checking each hash?
Upvotes: 2
Views: 3029
Reputation: 110755
This also works, though I would recommend @sawa's solutions.
Code
def all_nil?(array)
array.flat_map(&:values).compact.empty?
end
def each_all_nil?(array)
array.map { |h| h.values.compact.empty? }
end
Examples
array = [{dog: nil, cat: nil, bird: nil}, {rhino: nil, dog: nil, bird: nil}]
all_nil?(array) #=> true
each_all_nil?(array) #=> [true, true]
array = [{dog: nil, cat: nil, bird: nil}, {rhino: nil, dog: "woof", bird: nil}]
all_nil?(array) #=> false
each_all_nil?(array) #=> [true, false]
Explanation
array = [{dog: nil, cat: nil, bird: nil}, {rhino: nil, dog: "woof", bird: nil}]
For all_nil?
a = array.flat_map(&:values) #=> [nil, nil, nil, nil, "woof", nil]
b = a.compact #=> ["woof"]
b.empty? #=> false
For each_all_nil?
When mapping the first element of array
:
a = array.first #=> {:dog=>nil, :cat=>nil, :bird=>nil}
b = a.values #=> [nil, nil, nil]
c = b.compact #=> []
c.empty? #=> true
Upvotes: 1
Reputation: 34336
"Is there a better way than having to iterate through the array and checking each hash?"
Yes, you can make use of the Ruby's Enumerable all? to avoid looping through the array and checking each hash. The following are the two examples:
1.9.3p286 :001 > a = [{:a=>nil, :b=>nil}, {:a=>nil, :c=>nil}, {:d=> 1, :e=>nil}]
=> [{:a=>nil, :b=>nil}, {:a=>nil, :c=>nil}, {:d=>1, :e=>nil}]
1.9.3p286 :002 > a.all?{|h| h.values.all?(&:nil?)}
=> false
1.9.3p286 :003 > a = [{:a=>nil, :b=>nil}, {:a=>nil, :c=>nil}]
=> [{:a=>nil, :b=>nil}, {:a=>nil, :c=>nil}]
1.9.3p286 :004 > a.all?{|h| h.values.all?(&:nil?)}
=> true
Upvotes: 1
Reputation: 168269
array.all?{|h| h.values.all?(&:nil?)}
For a particular key key
:
array.all?{|h| h[key].nil?}
Upvotes: 8