【问题标题】:How do I merge two arrays of hashes based on same hash key value?如何基于相同的哈希键值合并两个哈希数组?
【发布时间】:2013-07-01 16:54:49
【问题描述】:

所以我有两个哈希数组:

a = [{"b"=>123,"c"=>456}, {"b"=>456,"c"=>555}]
b = [{"c"=>456,"d"=>789},  {"b"=>222,"c"=>444}]

如果键 c 的值在 ab 中相等,我将如何连接它们?这意味着我希望能够与a['c'] == b['c'] 的条件连接

这是我想要得到的结果:

final_array = [{"b"=>123,"c"=>456,"d"=>789}, {"b"=>456,"c"=>555}, {"b"=>222,"c"=>444}]

【问题讨论】:

标签: ruby


【解决方案1】:
a = [{"b"=>123,"c"=>456}, {"b"=>456,"c"=>555}]
b = [{"c"=>456,"d"=>789}, {"b"=>222,"c"=>444}]

p a.zip(b).map{|h1,h2| h1["c"] == h2["c"] ? h1.merge(h2) : [h1 ,h2]}.flatten
# => [{"b"=>123, "c"=>456, "d"=>789}, {"b"=>456, "c"=>555}, {"b"=>222, "c"=>444}]

【讨论】:

    【解决方案2】:
    a = [{"b"=>123,"c"=>456}, {"b"=>456,"c"=>555}]
    b = [{"c"=>456,"d"=>789},  {"b"=>222,"c"=>444}]
    
    def merge_hashes_with_equal_values(array_of_hashes, key)
      array_of_hashes.sort { |a,b| a[key] <=> b[key] }.
        chunk { |h| h[key] }.
        each_with_object([]) { |h, result|  result << h.last.inject(&:merge) }
    end
    
    p merge_hashes_with_equal_values(a + b, 'c')
    
    # => [{"b"=>222, "c"=>444}, {"c"=>456, "d"=>789, "b"=>123}, {"b"=>456, "c"=>555}]
    

    首先连接数组,然后将其传递给带有哈希键的方法以进行组合。对该数组进行排序,然后将要合并的散列放在另一个数组中,这使得合并更容易编程。在这里,我选择了#chunk 来检测连续运行的具有相等键的哈希进行合并,并选择#each_with_object 来编译最终数组。

    由于此方法需要一个数组来处理,因此起始数组的长度不需要相等,并且这些数组的顺序无关紧要。缺点是要操作的键必须包含可排序的值(例如,没有 nil)。

    这是解决问题的另一种方法,这个方法使用哈希来构建结果:

    def merge_hashes_with_equal_values(array_of_hashes, key)
      result = Hash.new { |h,k| h[k] = {} }
      remainder = []
      array_of_hashes.each_with_object(result) do |h, answer|
        if h.has_key?(key)
          answer[h.fetch(key)].merge!(h)
        else
          remainder << h
        end
      end.values + remainder
    end
    

    【讨论】:

      【解决方案3】:

      Enumerable#flat_mapHash#update 是实现此目的的完美方法:

      a = [{"b"=>123,"c"=>456}, {"b"=>456,"c"=>555}]    
      b = [{"c"=>456,"d"=>789}, {"b"=>222,"c"=>444}]
      p a.zip(b).flat_map{|k,v| next k.update(v) if k["c"] == v["c"];[k,v]}
      # >> [{"b"=>123, "c"=>456, "d"=>789}, {"b"=>456, "c"=>555}, {"b"=>222, "c"=>444}]
      

      【讨论】:

      • k.update 是做什么的?这如何专门合并c 相同但bd 不同的那些?
      • 这不会产生与原始发帖人要求的结果相似的任何东西。
      • @Edmund 由于网络中断,我无法编辑这篇文章。现在我完成了。
      猜你喜欢
      • 1970-01-01
      • 2019-05-03
      • 2015-06-13
      • 1970-01-01
      • 2013-02-24
      • 2018-02-12
      • 2017-09-26
      • 2016-10-07
      相关资源
      最近更新 更多