【问题标题】:Merge an array of hashes by key-value pair按键值对合并哈希数组
【发布时间】:2019-03-03 10:20:58
【问题描述】:

我有一个哈希数组如下:

[
  {'abc_id'=>'1234', 'def_id'=>[]},
  {'abc_id'=>'5678', 'def_id'=>['11', '22']},
  {'abc_id'=>'1234', 'def_id'=>['33', '44']},
  {'abc_id'=>'5678', 'def_id'=>['55', '66']}
]

我正在尝试将具有相同键值对的多个哈希组合成一个哈希。因此,我们有两对具有相同值的 'abc_id' 键,如下所示:

  • {'abc_id'=>'1234', 'def_id'=>[]}{'abc_id'=>'1234', 'def_id'=>['33', '44']}
  • {'abc_id'=>'5678', 'def_id'=>['11', '22']}{'abc_id'=>'5678', 'def_id'=>['55', '66']}

我希望将具有相同键值对的多个散列合并为一个单独的散列。对于上面的两对,它们应该分别是:

  • {'abc_id'=>'1234', 'def_id'=>['33', '44']}
  • {'abc_id'=>'5678', 'def_id'=>['11', '22', '55', '66']}

【问题讨论】:

  • edit您的问题包括您编写的代码以尝试解决此问题作为代码(不是屏幕截图)在答案中(不在外部网站上),并准确地描述该代码的问题,以及它为什么不能解决您的问题。包括完整的错误消息,如果你得到任何(同样,作为文本和问题内),以及你得到的任何结果。
  • 进一步@Jörg的评论,读者经常想剪切和粘贴提问者的代码,如果它呈现在图片中是无法做到的,并且指向外部站点的链接将来可能会被破坏,所以问题不应该依赖于这些链接的内容。

标签: ruby hash key-value


【解决方案1】:

或多或少的通用和可扩展变体是:

input.
  group_by { |h| h['abc_id'] }.
  map do |k, v|
    v.reduce do |acc, arr|
      #  use `+` instead of `|` to save duplicates  ⇓⇓⇓
      acc.merge(arr) { |_, v1, v2| Array === v1 ? v1 | v2 : v1 }
    end
  end
#⇒ [{"abc_id"=>"1234", "def_id"=>["33", "44"]},
#   {"abc_id"=>"5678", "def_id"=>["11", "22", "55", "66"]}]

【讨论】:

    【解决方案2】:

    还有一个选项:

    array
      .map.with_object({}) { |h, hh| hh[h['abc_id']].nil? ? hh[h['abc_id']] = h['def_id'] : hh[h['abc_id']] += h['def_id'] }
      .map{ |k, v| {'abc_id' => k, 'def_id' => v} }
    

    第一部分返回

    # {"1234"=>["33", "44"], "5678"=>["11", "22", "55", "66"]}
    

    第二部分重建原始结构,返回:

    #=> [{"abc_id"=>"1234", "def_id"=>["33", "44"]}, {"abc_id"=>"5678", "def_id"=>["11", "22", "55", "66"]}]
    

    【讨论】:

      【解决方案3】:

      可以使用Hash#update(又名merge!)和Hash#merge 的形式,它们使用一个块来确定在被合并的两个散列中存在的键的值。这需要在两个层面上完成。

      arr为问题中给出的数组,这些方法的使用如下。

      arr.each_with_object({}) do |g,h|
        h.update(g['abc_id']=>g) do |_,o,n|
          o.merge(n) { |k,oo,nn| k=='def_id' ? oo+nn : oo }
        end
      end.values
        #=> [{"abc_id"=>"1234", "def_id"=>["33", "44"]},
        #    {"abc_id"=>"5678", "def_id"=>["11", "22", "55", "66"]}]
      

      有关块变量 _onkoonn 的说明,请参阅文档。我用下划线表示公共键 用update告诉读者它没有用于块计算。

      注意Hash#values的接收者如下。

      { "1234"=>{ "abc_id"=>"1234", "def_id"=>["33", "44"] },
        "5678"=>{ "abc_id"=>"5678", "def_id"=>["11", "22", "55", "66"] } }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-29
        • 2011-05-26
        • 2015-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多