Check if a hash's keys include all of a set of keys

Ruby

Ruby Problem Overview


I'm looking for a better way to do

if hash.key? :a &&
   hash.key? :b &&
   hash.key? :c &&
   hash.key? :d

preferably something like

hash.includes_keys? [ :a, :b, :c, :d ] 

I came up with

hash.keys & [:a, :b, :c, :d] == [:a, :b, :c, :d]

but I dont like having to add the array twice though

Ruby Solutions


Solution 1 - Ruby

%i[a b c d].all? {|s| hash.key? s}

Solution 2 - Ruby

@Mori's way is best, but here's another way:

([:a, :b, :c, :d] - hash.keys).empty?

or

hash.slice(:a, :b, :c, :d).size == 4

Solution 3 - Ruby

Just in the spirit of TIMTOWTDI, here's another way. If you require 'set' (in the std lib) then you can do this:

Set[:a,:b,:c,:d].subset? hash.keys.to_set

Solution 4 - Ruby

You can get a list of missing keys this way:

expected_keys = [:a, :b, :c, :d]
missing_keys = expected_keys - hash.keys

If you just want to see if there are any missing keys:

(expected_keys - hash.keys).empty?

Solution 5 - Ruby

I like this way to solve this:

subset = [:a, :b, :c, :d]
subset & hash.keys == subset

It is fast and clear.

Solution 6 - Ruby

Here is my solution:

(also given as answer at)

class Hash
	# doesn't check recursively
	def same_keys?(compare)
      return unless compare.class == Hash
	 	
      self.size == compare.size && self.keys.all? { |s| compare.key?(s) }
	end
end

a = c = {  a: nil,    b: "whatever1",  c: 1.14,     d: false  }
b     = {  a: "foo",  b: "whatever2",  c: 2.14,   "d": false  }
d     = {  a: "bar",  b: "whatever3",  c: 3.14,               }

puts a.same_keys?(b)                    # => true
puts a.same_keys?(c)                    # => true
puts a.same_keys?(d)                    # => false   
puts a.same_keys?(false).inspect        # => nil
puts a.same_keys?("jack").inspect       # => nil
puts a.same_keys?({}).inspect           # => false

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGreg GuidaView Question on Stackoverflow
Solution 1 - RubyMoriView Answer on Stackoverflow
Solution 2 - RubyJohn DouthatView Answer on Stackoverflow
Solution 3 - RubyMark ThomasView Answer on Stackoverflow
Solution 4 - RubyChris HansonView Answer on Stackoverflow
Solution 5 - RubySeb WilgoszView Answer on Stackoverflow
Solution 6 - RubyAlphonsView Answer on Stackoverflow