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

后端 未结 6 593
天命终不由人
天命终不由人 2020-12-24 10:38

I\'m looking for a better way to do

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

prefer

相关标签:
6条回答
  • 2020-12-24 10:57

    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
    
    0 讨论(0)
  • 2020-12-24 11:02
    %i[a b c d].all? {|s| hash.key? s}
    
    0 讨论(0)
  • 2020-12-24 11:06

    I like this way to solve this:

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

    It is fast and clear.

    0 讨论(0)
  • 2020-12-24 11:11

    @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
    
    0 讨论(0)
  • 2020-12-24 11:17

    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
    
    0 讨论(0)
  • 2020-12-24 11:20

    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?
    
    0 讨论(0)
提交回复
热议问题