Ruby 如何合并数组的重复元素,同时保持值的组合?
我有这样的想法:Ruby 如何合并数组的重复元素,同时保持值的组合?,ruby,Ruby,我有这样的想法: prods = [{"1050" => {"key" => "value", "key2" => "value2"}}, {"1050" => {"key" => "value", "key2" => "value2"}}, {"6650" => {"key" => "value", "key2" => "value2"}}, {"6650" => {"key" =
prods = [{"1050" => {"key" => "value", "key2" => "value2"}},
{"1050" => {"key" => "value", "key2" => "value2"}},
{"6650" => {"key" => "value", "key2" => "value2"}},
{"6650" => {"key" => "value", "key2" => "value2"}}]
我希望合并重复项,但保留键值对,如下所示
prods = [{"1050" => [{"key" => "value", "key2" => "value2"},
{"key" => "value", "key2" => "value2"}}],
{"6650" => [{"key" => "value", "key2" => "value2"},
{"key" => "value", "key2" => "value2"}}]
]
这可能吗?h=Hash.new{[]}这会在密钥不存在时创建一个新数组
h = Hash.new {[]} # this creates a new array when a key doesn't exist
prods.each do |prod|
prod.each{ |key,val| h[key] = h[key] << val }
end
puts h
每一个都做|戳|
prod.each{| key,val | h[key]=h[key]下面是我建议的解决方案:
results =
prods.each_with_object(Hash.new([])) do |hash, results|
key = hash.keys.first
values = hash.values
results[key] += values
end
results = results.map { |k, v| Hash[k, v] }
def find_hash(haystack, needle)
haystack.index { |hay| hay.keys.first == needle }
end
results =
prods.each_with_object(Array.new) do |hash, results|
key = hash.keys.first
values = hash.values
idx = find_hash(results, key)
if idx
results[idx][key] += values
else
results << Hash[key, values]
end
end
在这个解决方案中,我只使用一个带有默认值的散列来处理重复项,然后转换为所需的输出格式
替代解决方案:
results =
prods.each_with_object(Hash.new([])) do |hash, results|
key = hash.keys.first
values = hash.values
results[key] += values
end
results = results.map { |k, v| Hash[k, v] }
def find_hash(haystack, needle)
haystack.index { |hay| hay.keys.first == needle }
end
results =
prods.each_with_object(Array.new) do |hash, results|
key = hash.keys.first
values = hash.values
idx = find_hash(results, key)
if idx
results[idx][key] += values
else
results << Hash[key, values]
end
end
def find_散列(草堆、针)
haystack.index{| hay | hay.keys.first==针}
结束
结果=
prods.each_with_object(Array.new)do| hash,results|
key=hash.keys.first
values=hash.values
idx=查找\u散列(结果、键)
如果idx
结果[idx][key]+=值
其他的
结果这是众多方法中的一种
代码
def combine(prods)
prods.map(&:flatten)
.each_with_object(Hash.new {|h,k| h[k]=[]}) { |(k,v),h| h[k] << v }
.map { |k,v| { k=>v } }
end
现在让我们重新定义prods:
prods = [{"1050" => {"keya" => "value1", "keyb" => "value1"}},
{"1050" => {"keya" => "value2", "keyb" => "value2"}},
{"6650" => {"keya" => "value3", "keyb" => "value3"}},
{"6650" => {"keya" => "value4", "keyb" => "value4"}}]
combine(prods)
#=> [{"1050"=>[{"keya"=>"value1", "keyb"=>"value1"},
# {"keya"=>"value2", "keyb"=>"value2"}]},
# {"6650"=>[{"keya"=>"value3", "keyb"=>"value3"},
# {"keya"=>"value4", "keyb"=>"value4"}]}]
解释
以下是步骤:
a = prods.map(&:flatten)
#=> [["1050", {"key"=>"value", "key2"=>"value2"}],
# ["1050", {"key"=>"value", "key2"=>"value2"}],
# ["6650", {"key"=>"value", "key2"=>"value2"}],
# ["6650", {"key"=>"value", "key2"=>"value2"}]]
h = a.each_with_object(Hash.new {|h,k| h[k]=[]}) { |(k,v),h| h[k] << v }
#=> {"1050"=>[{"key"=>"value", "key2"=>"value2"},
# {"key"=>"value", "key2"=>"value2"}],
# "6650"=>[{"key"=>"value", "key2"=>"value2"},
# {"key"=>"value", "key2"=>"value2"}]}
生成上面显示的结果
在计算h
时,对象是块变量h
的值。最初,h
是一个空哈希,定义如下:
Hash.new {|h,k| h[k]=[]}
(k,v),h = [["1050", {"key"=>"value", "key2"=>"value2"}], {}]
#=> [["1050", {"key"=>"value", "key2"=>"value2"}], {}]
k #=> "1050"
v #=> {"key"=>"value", "key2"=>"value2"}
h #=> {}
(k,v),h = [["1050", {"key"=>"value", "key2"=>"value2"}],
{ "1050"=>[{"key"=>"value", "key2"=>"value2"}] }]
k #=> "1050"
v #=> {"key"=>"value", "key2"=>"value2"}
h #=> {"1050"=>[{"key"=>"value", "key2"=>"value2"}]}
块给出散列的默认值。这表示如果h
是散列,而k
是要添加到散列的键,则其默认值是空数组。传递到每个带有\u对象的\u的块的a
的第一个值是:
["1050", {"key"=>"value", "key2"=>"value2"}]
因此,块变量分配如下:
Hash.new {|h,k| h[k]=[]}
(k,v),h = [["1050", {"key"=>"value", "key2"=>"value2"}], {}]
#=> [["1050", {"key"=>"value", "key2"=>"value2"}], {}]
k #=> "1050"
v #=> {"key"=>"value", "key2"=>"value2"}
h #=> {}
(k,v),h = [["1050", {"key"=>"value", "key2"=>"value2"}],
{ "1050"=>[{"key"=>"value", "key2"=>"value2"}] }]
k #=> "1050"
v #=> {"key"=>"value", "key2"=>"value2"}
h #=> {"1050"=>[{"key"=>"value", "key2"=>"value2"}]}
区块计算为:
h[k] << v
散列h
现在是:
h #=> { "1050"=>[{"key"=>"value", "key2"=>"value2"}] }
a
的下一个值被传递到块,导致块变量更新如下:
Hash.new {|h,k| h[k]=[]}
(k,v),h = [["1050", {"key"=>"value", "key2"=>"value2"}], {}]
#=> [["1050", {"key"=>"value", "key2"=>"value2"}], {}]
k #=> "1050"
v #=> {"key"=>"value", "key2"=>"value2"}
h #=> {}
(k,v),h = [["1050", {"key"=>"value", "key2"=>"value2"}],
{ "1050"=>[{"key"=>"value", "key2"=>"value2"}] }]
k #=> "1050"
v #=> {"key"=>"value", "key2"=>"value2"}
h #=> {"1050"=>[{"key"=>"value", "key2"=>"value2"}]}
因此,区块计算为:
h[k] << v
# h["1050"] << {"key"=>"value", "key2"=>"value2"}
其余的计算都是类似的。您的答案并不完全符合此问题的要求。如果您查看“期望输出”,您会注意到“1050”和“6650”是如何显示的是单独的散列。如果两个键都是同一散列的一部分,则代码生成散列。如果所有键的值都不相同,则会更好。prods
是否必须是散列数组?如果prods
最初是散列,则可能不会出现此问题…请注意,这里有一个到散列的快速转换:prods.ea带有{}对象({})的Chu{p,h | k,v=p.to_a[0];(h[k]|=[]))