Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何合并数组的重复元素,同时保持值的组合?_Ruby - Fatal编程技术网

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]|=[]))