红宝石-检查哈希的键是否包含所有键集

我正在寻找更好的方法

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

最好是这样的

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

我想出了

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

但我不喜欢不得不两次添加数组

Greg Guida asked 2019-11-14T06:37:26Z
6个解决方案
103 votes
%i[a b c d].all? {|s| hash.key? s}
Mori answered 2019-11-14T06:37:40Z
20 votes

@Mori的方法最好,但这是另一种方法:

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

要么

hash.slice(:a, :b, :c, :d).size == 4
John Douthat answered 2019-11-14T06:38:06Z
14 votes

秉承TIMTOWTDI的精神,这是另一种方式。 如果您是require 'set'(在标准库中),则可以执行以下操作:

Set[:a,:b,:c,:d].subset? hash.keys.to_set
Mark Thomas answered 2019-11-14T06:38:31Z
7 votes

您可以通过以下方式获取缺少的键的列表:

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

如果您只想查看是否缺少任何键:

(expected_keys - hash.keys).empty?
Chris Hanson answered 2019-11-14T06:39:06Z
6 votes

我喜欢这种方式来解决这个问题:

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

快速而清晰。

swilgosz answered 2019-11-14T06:39:38Z
1 votes

这是我的解决方案:

(也作为答案提供)

class Hash
    # doesn't check recursively
    def same_keys?(compare)
        if compare.class == Hash
            if self.size == compare.size
               self.keys.all? {|s| compare.key?(s)}
            else
                return false
            end
        else
            nil
        end
    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
Alphons answered 2019-11-14T06:40:04Z
translate from https://stackoverflow.com:/questions/11552490/check-if-a-hashs-keys-include-all-of-a-set-of-keys