[英]Array of Hashes to Hash Conversion while preventing Key Override
您将如何转换:
x = [
{"a" => ["a","b","c","d","e"]},
{"f" => ["f","g","h","i","j","k","l","m","n"]},
{"f" => ["o","p"]}
]
进入:
{
"a"=>["a", "b", "c", "d", "e"],
"f" => ["f","g","h","i","j","k","l","m","n"]},
"f01"=>["o", "p"]
}
我原来是用
x.reduce({},:update)
但这会覆盖第一个“ f”(因为键是唯一的)。
我一直在寻找答案,但没有找到在这种情况下可行的任何方法。
更改密钥后,生成的哈希将导致一个非常困难的问题:如何轻松查找生成的哈希及其数组?
我建议重新考虑您想要的哈希类型。 与其创建将很难查找并与原始哈希键具有脆弱关联的新哈希键,而是重用原始键并创建指向数组数组的哈希键。 从更简单的哈希开始数组开始:
x = [ {'a' => ['a', 'b']}, {'f' => ['f', 'g']}, {'f' => ['o', 'p']} ]
这是代码:
hash = x.each_with_object(Hash.new{ |h, k| h[k] = [] }) { |e, h|
k, v = e.flatten
h[k] << v
}
pp hash
这是输出:
{"a"=>[["a", "b"]], "f"=>[["f", "g"], ["o", "p"]]}
查找变得更加简单:
hash['f'][0]
# => ["f", "g"]
hash['f'].last
# => ["o", "p"]
您可以保持原始数组的分离,同时获得更逻辑,更简单的查找。
如果您需要知道为哈希分配了多少个子数组,也很容易:
hash['f'].size
# => 2
如果您想遍历所有的'f'
条目,而这在您的设计中会变得复杂而困难,只需执行以下操作:
hash['f'].each do |f|
...
end
要么:
hash['f'].map { |f|
...
}
假设f01
的01
部分只是一个计数器,而您不关心格式化该数字,则可以执行以下操作:
def reduce_update_incr(arr)
key_count = {}
arr.reduce({}) do |memo,h|
h.each do |k,v|
k = k + (key_count[k]=(key_count[k]||0)+1).to_s if memo.include?(k)
memo[k] = v
end
memo
end
end
reduce_update_incr(x)
# {"a"=>["a", "b", "c", "d", "e"],
# "f"=>["f", "g", "h", "i", "j", "k", "l", "m", "n"],
# "f1"=>["o", "p"]}
uck
您可以按以下方式使用inject
:
> x.inject({}){|r,h| r[h.keys.first] ||= [] ; r[h.keys.first] << h.values.first; r}
=> {"a"=>[["a", "b", "c", "d", "e"]],
"f"=>[["f", "g", "h", "i", "j", "k", "l", "m", "n"], ["o", "p"]]}
请注意,您将为同一密钥获得多个阵列。 (即"f"
)
产生的哈希值与您要求的哈希值略有不同,但使用起来可能会更容易,因为不会与修改后的键混淆。
x = [
{"a" => ["a","b","c","d","e"]},
{"f" => ["f","g","h","i","j","k","l","m","n"]},
{"f" => ["o","p"]}
]
res = x.collect{|d| d.first}.each_with_object({}) do |(k,v), h, n = "00"|
(k += n.next!) if (h.key? k)
h[k] = v
end
res == {
"a"=>["a", "b", "c", "d", "e"],
"f" => ["f","g","h","i","j","k","l","m","n"],
"f01"=>["o", "p"]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.