Reputation: 895
I have a hash, whose values are true
or false
. What is the most Ruby-esque way to see if all the values of a given sub-hash of this hash are the same?
h[:a] = true
h[:b] = true
h[:c] = true
h[:d] = false
[h[:a], h[:b], h[:c]].include? false
[h[:a], h[:b], h[:c]].include? true
Is there a better way to write this?
Upvotes: 2
Views: 120
Reputation: 15488
Another general-purpose method:
whatever.uniq.size == 1
This tests directly whether all the values in whatever
are the same. So, in your case,
h.values_at(:a, :b, :c).uniq.size == 1
Upvotes: 0
Reputation: 80065
values_at
is the method to get a collection of values out of a Hash:
h.values_at(:a,:b,:c).all? #are they all true?
h.values_at(:a,:b,:c).any? #is at least one of them true?
h.values_at(:a,:b,:c).none? #are they all false?
Upvotes: 8
Reputation: 160191
> [h[:a], h[:b], h[:c]].all?
=> true
> [h[:a], h[:b], h[:d]].all?
=> false
> [h[:a], h[:b], h[:d]].all?
=> false
> [h[:d]].none?
=> true
Depending on your needs it might be cleaner to write something like:
> [:a, :b, :c].all? { |key| h[key] }
=> true
> [:a, :b, :d].all? { |key| h[key] }
=> false
> [:a, :d].none? { |key| h[key] }
=> false
> [:d].none? { |key| h[key] }
=> true
Upvotes: 1
Reputation: 2902
If all you want to do is evaluate they are ALL true
or they are ALL false
:
h[:a] && h[:b] && h[:c] && h[:d] # => false
!(h[:a] || h[:b] || h[:c] || h[:d]) # => false
h[:a] && h[:b] && h[:c] # => true
!h[:d] # => true
Otherwise, as Dave Newton pointed out, you can use the #all?
, #any?
and #none?
methods.
Upvotes: 1