如何判断Ruby散列是否是另一个散列的子集(或包含)?红宝石哈希检查是子集?
例如:
hash = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
hash.include_hash?({}) # true
hash.include_hash?({f: 6, c: 3}) # true
hash.include_hash?({f: 6, c: 1}) # false
如何判断Ruby散列是否是另一个散列的子集(或包含)?红宝石哈希检查是子集?
例如:
hash = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
hash.include_hash?({}) # true
hash.include_hash?({f: 6, c: 3}) # true
hash.include_hash?({f: 6, c: 1}) # false
由于红宝石2.3还可以执行以下操作来检查,如果这是一个子集
hash = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
{} <= hash # true
{f: 6, c: 3} <= hash # true
{f: 6, c: 1} <= hash # false
是我脑子里浮现使用Hash#merge
方法解决办法:
class Hash
def include_hash?(hash)
merge(hash) == self
end
end
hash = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
hash.include_hash?({})
# => true
hash.include_hash?(f: 6, c:3)
# => true
hash.include_hash?(f: 6, c:1)
# => false
你可以在哈希转换为sets,也比使用方法subset?
和superset?
进行检查(或它们各自的别名<=
和>=
):
require 'set'
hash.to_set.superset?({}.to_set)
# => true
hash.to_set >= {a: 1}.to_set
# => true
{a: 2}.to_set <= hash.to_set
# => false
更新:所提出的解决方案的标杆:
require 'fruity'
require 'set'
hash = ('aa'..'zz').zip('aa'..'zz').to_h
# {"aa"=>"aa", "ab"=>"ab", ...
find = ('aa'..'zz').zip('aa'..'zz').select { |k, _| k[0] == k[1] }.to_h
# {"aa"=>"aa", "bb"=>"bb", ...
compare(
toro2k: -> { hash.to_set >= find.to_set },
MarekLipka: -> { hash.merge(find) == hash },
CarySwoveland: -> { (find.to_a - hash.to_a).empty? },
ArupRakshit: -> { arr = hash.to_a; find.all? { |pair| arr.include?(pair) } }
)
结果:
Running each test 2 times. Test will take about 1 second.
MarekLipka is faster than toro2k by 3x ± 0.1
toro2k is faster than CarySwoveland by 39.99999999999999% ± 10.0%
CarySwoveland is faster than ArupRakshit by 1.9x ± 0.1
你可以这样做:
def include_hash?(hash,subset_hash)
arr = hash.to_a
subset_hash.all? { |pair| arr.include?(pair) }
end
任何人都可以检查'subset_hash.all? {| pair | arr.include?(pair)}'也在工作或不在...我远离电脑,所以无法测试相同的结果。 –
我检查了一些测试用例,它似乎能够正常工作。 – ma11hew28
@MattDiPasquale谢谢...我现在已经更新了它.. –
阵列的区别似乎最简单的:
class Hash
def include_hash?(h)
(h.to_a - to_a).empty?
end
end
h = {a: 1, b: 2}
h.include_hash?({b: 2}) #=> true
h.include_hash?({b: 3}) #=> false
我明白'(h.to_a - to_a)'..但是为了更好的可读性,...(h.to_a - self.to_a)'...... IMO –
@Arup,我尊敬地不同意,但我知道你的观点被许多人共享其他。 Imo,'self.to_a'表明这里需要'self'(就像它后面跟着一个访问器或'class'一样)。我认为最好避免在不需要时使用'self'。如果读者被'to_a'弄糊涂而没有'self',他们会很快弄清楚,并且在讨价还价中学到一些东西。 –
马特,你似乎已经被赋予与(HTTP的[富人的尴尬]://dictionary.cambridge。组织/字典/英国/ AN-尴尬-的-财富)。 (链接英语为第二语言的人)。在SO上获得四个四分之一的质量答案是非常罕见的。 –