Ruby中Hash#delete的不可变替代方案咨询
Ruby中Hash#delete的不可变替代方案
当然有啦!Ruby里确实有几种方式可以实现不修改原哈希的“删除”操作,替代原生的Hash#delete(毕竟原生方法是破坏性的,会直接改动原对象)。下面给你几个实用的方案:
使用
Hash#except(Ruby 2.5+ 原生支持)
这是最直接的官方解决方案,专门用来返回移除指定键后的新哈希,完全不会改动原哈希。示例:hash = {a: 1, b: 2} new_hash = hash.except(:a) new_hash # => {:b=>2} hash # => {:a=>1, :b=>2} 原哈希毫无变化它还支持一次排除多个键,比如
hash.except(:a, :b),非常方便。旧Ruby版本用
Hash#reject
如果你的Ruby版本低于2.5(比如2.4及更早),没有except方法,可以用reject来实现。reject会返回一个新哈希,包含所有不满足块条件的键值对:hash = {a: 1, b: 2} new_hash = hash.reject { |key, _| key == :a } new_hash # => {:b=>2} hash # => {:a=>1, :b=>2}要排除多个键的话,调整块条件即可:
hash.reject { |k, _| [:a, :b].include?(k) }先复制再删除(通用变通方案)
如果你需要和原生delete的返回值逻辑对齐(比如拿到被删除的值),可以先复制原哈希,再在副本上执行delete:hash = {a: 1} hash_copy = hash.dup deleted_value = hash_copy.delete(:a) deleted_value # => 1 hash_copy # => {} hash # => {:a=>1} 原哈希依旧完好也可以写成一行:
hash.dup.tap { |h| h.delete(:a) },直接得到删除后的新哈希。
总结一下,优先用Hash#except,它是Ruby官方为这种不可变场景设计的方法,简洁又高效。如果是旧版本,reject是不错的替代,而复制后删除则是兼容性最好的通用方案。
内容的提问来源于stack exchange,提问作者Ben G
相关产品推荐
相关产品推荐

