Ruby中Hash不允许存储重复键的默认行为能否自定义修改?
核心结论
Ruby 标准 Hash 结构本身不支持重复键,这是其底层核心设计规则,无法通过修改默认配置直接实现你需要的同键名保留多个独立条目的效果。你期望得到的 {"key1"=>{:A=>{:id=>"1"}}, "key1"=>{:B=>{:id=>"2"}}} 本身不符合 Ruby 标准 Hash 的规范,无法作为原生 Hash 对象存在。
可选实现方案
如果不想用分组把值合并为数组的方案,可以根据你的使用场景选择以下方式:
方案1:保留键值对数组结构,不转为Hash
不需要改动原有生成逻辑,仅去掉 .to_h 调用,直接保留 zip 生成的二维数组即可,该结构完整保留所有重复键条目,遍历、匹配逻辑和Hash差异很小:
keys_array = [ 'key1', 'key1' ] values_array = [{"A": { "id": "1" }},{"B": { "id": "2" }}] results = keys_array.zip(values_array) # 结果为:[["key1", {:A=>{:id=>"1"}}], ["key1", {:B=>{:id=>"2"}}]]
你可以正常遍历该数组处理所有条目,也可以通过筛选快速获取某个key对应的所有值:
# 获取所有key1对应的值 key1_values = results.select { |k, v| k == 'key1' }.map(&:last)
方案2:自定义支持重复键的类Hash结构
如果你需要类Hash的访问、赋值能力,可以自己实现一个极简的重复键Hash类,完全兼容你要的输出格式:
class DuplicateKeyHash def initialize @pairs = [] end # 赋值逻辑,直接追加不覆盖 def []=(key, value) @pairs << [key, value] end # 取值逻辑,返回指定key对应的所有值 def [](key) @pairs.select { |k, _| k == key }.map(&:last) end # 自定义字符串输出,完全匹配你需要的格式 def to_s "{#{@pairs.map { |k, v| "#{k.inspect}=>#{v.inspect}" }.join(', ')}}" end end # 使用示例 h = DuplicateKeyHash.new keys_array.zip(values_array).each { |k, v| h[k] = v } puts h.to_s # 输出:{"key1"=>{:A=>{:id=>"1"}}, "key1"=>{:B=>{:id=>"2"}}}
内容的提问来源于stack exchange,提问作者Shamila
相关产品推荐
相关产品推荐

