Ruby 如何基于两个哈希的共有键对应值实现哈希比较
优化实现方案
写法1(兼容所有Ruby版本,性能更优)
def common_keys_equal?(h1, h2) common_keys = h1.keys & h2.keys common_keys.any? && common_keys.all? { |k| h1[k] == h2[k] } end
写法2(Ruby 2.5+ 语法糖写法,可读性更高)
def common_keys_equal?(h1, h2) h1.slice(*h2.keys) == h2.slice(*h1.keys) && h1.keys.intersect?(h2.keys) end
Hash#slice为Ruby 2.5新增内置方法,低版本环境可引入ActiveSupport核心扩展或者自行实现该方法
原方案及优化方案需要注意的边界场景
- 键类型匹配问题:Ruby中字符串键和符号键是完全不同的键,例如
{'a' => 1}和{a: 1}会被判定为无共有键返回false,若业务中存在键类型需要模糊匹配的场景,需提前统一键的类型再做比较 - 复杂值的比较逻辑:如果哈希的值是数组、哈希、自定义类实例等非基础类型,
==默认走引用相等判断,若需要深度值比较,需要将比较逻辑替换为递归深度比较 - 空哈希处理:只要参与比较的任意一个哈希为空,双方必然无共有键,会直接返回false,符合你给出的需求规则
- 超大哈希性能:当哈希键数量达到十万级以上时,遍历键逐个比较的
all?写法性能优于原方案的values_at写法,因为不需要额外生成两个存储共有键对应值的临时数组
测试验证
修正你示例代码中hash4的语法笔误(e = 5改为e => 5)后,上述方法可以完全匹配你预期的结果:
hash1 = {'a' => 1, 'b' => 2} hash2 = {'a' => 1, 'b' => 2, 'd' => 3} hash3 = {'a' => 1, 'b' => 2, 'c' => 4, 'd' => 3} hash4 = {'c' => 4, 'd' => 3, 'e' => 5} p common_keys_equal?(hash1, hash2) # => true p common_keys_equal?(hash1, hash3) # => true p common_keys_equal?(hash1, hash4) # => false p common_keys_equal?(hash2, hash3) # => true
内容的提问来源于stack exchange,提问作者Warden
相关产品推荐
相关产品推荐

