当前位置: 首页 > 知识库问答 >
问题:

根据多个键的比较合并两个哈希数组

蓬意致
2023-03-14

我有两个哈希数组:

a1 = [{ ID: 12496, name: "Robert", email: "robert@hotmail.com" }, ...]
a2 = [{ ID: 12496, name: "Robert", ORDER_NO: 5511426 }, ...]

我想在< code>a2中找到其< code>ID和< code>name字段与< code>a1中条目的< code>ID和< code>name字段相匹配的散列(不考虑< code>email或任何其他进入< code>a2的项目),然后将< code>ORDER_NO的值合并到< code>a1散列中也就是说,以下列方式结束:

[{ ID: 12496, name: "Robert", email: "robert@example.com", ORDER_NO: 5511426 } ...]

我也想忽略 a2 中存在的元素,但不忽略 a1 中的元素。

我正在执行以下操作:

a1.each do |a1_hash|
  matching_hash = a2.find { |a2_hash| data_matches?(a1_hash, a2_hash) } if a2.present?
  a1_hash["ORDER_NO"] = a2_hash["ORDER_NO"] if matching_hash.present?
  a2.delete(a2_hash)
end

但是有没有更快的方法呢?

共有3个答案

丰誉
2023-03-14

你可以在合并之前通过请求的属性把东西放在一个hash中来更快地完成合并,然后获取值。输入中值的唯一性)。

x1 = a1.reduce({}){|m, h| m[h.select{|k| [:ID, :name].include? k}] = h;m}
x2 = a2.reduce({}){|m, h| m[h.select{|k| [:ID, :name].include? k}] = h;m}
x1.merge(x2.select{|k,v| x1.key?(k)}){|k,o,n| o.merge(n)}.values

使用示例数据运行:

a1 = [{ ID: 12496, name: "Robert", email: "robert@hotmail.com" }]
=> [{:ID=>12496, :name=>"Robert", :email=>"robert@hotmail.com"}]

a2 = [{ ID: 12496, name: "Robert", ORDER_NO: 5511426 }]
=> [{:ID=>12496, :name=>"Robert", :ORDER_NO=>5511426}]

x1 = a1.reduce({}){|m, h| m[h.select{|k| [:ID, :name].include? k}] = h;m}
=> {{:ID=>12496, :name=>"Robert"}=>{:ID=>12496, :name=>"Robert", :email=>"robert@hotmail.com"}}

x2 = a2.reduce({}){|m, h| m[h.select{|k| [:ID, :name].include? k}] = h;m}
=> {{:ID=>12496, :name=>"Robert"}=>{:ID=>12496, :name=>"Robert", :ORDER_NO=>5511426}}

x1.merge(x2.select{|k,v| x1.key?(k)}){|k,o,n| o.merge(n)}.values
=> [{:ID=>12496, :name=>"Robert", :email=>"robert@hotmail.com", :ORDER_NO=>5511426}]
翟冷勋
2023-03-14
匿名用户

假设:

a1 = [{ ID: 12496, name: "Robert", email: "robert@hotmail.com" },
      { ID: 12497, name: "Lola",   email: "lola@hotmail.com" },
      { ID: 12498, name: "Hank",   email: "hank@hotmail.com" }]

a2 = [{ ID: 12497, name: "Lola",   ORDER_NO: 5511427 },
      { ID: 12496, name: "Robert", ORDER_NO: 5511426 }]

我建议您首先构建散列:

h2 = a2.each_with_object({}) { |g,h| h[[g[:ID], g[:name]]]=g[:ORDER_NO] }
  #=> { [12497, "Lola"]=>5511427, [12496, "Robert"]=>5511426 }

然后简单地遍历a1的元素,在适当的地方添加键值对:

a1.each do |g|
  k = [g[:ID],g[:name]]
  g[:ORDER_NO] = h2[k] if h2.key?(k)
end
a1
  #=> [{ID: 12496, name: "Robert", email: "robert@hotmail.com", ORDER_NO: 5511426},
  #    {ID: 12497, name: "Lola",   email: "lola@hotmail.com",   ORDER_NO: 5511427},
  #    {ID: 12498, name: "Hank",   email: "hank@hotmail.com"}]

我假设:

    < li >对于< code>ID和< code>:name,在< code>a1中没有两个元素(哈希)具有相同的值; < li >对于< code>ID和< code>:name,在< code>a2中没有两个元素(哈希)具有相同的值;和 < li> a1将被修改。

荆哲
2023-03-14

这可以使用Ruby的一些内置方法非常干净地完成。

a1 = [{ ID: 12496, name: "Robert", email: "robert@hotmail.com" },
      { ID: 12497, name: "Lola",   email: "lola@hotmail.com" },
      { ID: 12498, name: "Hank",   email: "hank@hotmail.com" }]

a2 = [{ ID: 12497, name: "Lola",   ORDER_NO: 5511427 },
      { ID: 12496, name: "Robert", ORDER_NO: 5511426 }]

index = a2.group_by{|entry| [entry[:ID], entry[:name]] }
a1.map{|entry| (index[[entry[:ID], entry[:name]]] || []).reduce(entry, :merge) }

结果:

[{:ID=>12496, :name=>"Robert", :email=>"robert@hotmail.com", :ORDER_NO=>5511426},
 {:ID=>12497, :name=>"Lola",   :email=>"lola@hotmail.com",   :ORDER_NO=>5511427},
 {:ID=>12498, :name=>"Hank",   :email=>"hank@hotmail.com"}]

细分:

首先,我们使用< code>group_by来构建a2中的条目表,这些条目可能会合并到a1的条目中。我们根据id和name键对该表进行索引,因为这些是我们用来确定哪些条目匹配的因素:

index = a2.group_by{|entry| [entry[:ID], entry[:name]] }

这会产生以下结果:

{[12497, "Lola"]=>[{:ID=>12497,   :name=>"Lola",   :ORDER_NO=>5511427}], 
 [12496, "Robert"]=>[{:ID=>12496, :name=>"Robert", :ORDER_NO=>5511426}]}

接下来,我们a1中的每个条目映射到其新形式,合并索引中的序号:

a1.map{|entry|
  # ...
}

为了获得我们将每个条目映射到的值,我们首先获取一个数组,该数组包含a2中的所有值,这些值适合与a1的此条目合并:

(index[[entry[:ID], entry[:name]]] || [])

这将返回类似<code>〔{:ID=

然后,从a1的条目开始,我们使用合并将索引中的所有条目减少到一个散列(例如减少(条目,:合并)),这会产生一个类似{: ID=的条目

如果您不熟悉 Ruby 核心库中的方法,所有这些可能看起来有点复杂。但是,一旦你理解了简单的函数式编程概念,如map和reduce,想出这样简单而强大的解决方案真的不是那么困难。

 类似资料:
  • 问题内容: 我有两个数组: 阵列1: 和数组2: 我需要基于合并这两个数组,并获得此: 我如何在不迭代低谷的情况下做到这一点? 问题答案: 你可以这样- 如果和的顺序不同,请使用以下代码: 如果和以相同的顺序使用

  • 我在尝试遍历两个哈希数组时遇到问题。我的哈希值如下所示: 在我检查h1和h2中“name”字段的哈希值后,我需要将这两个哈希组合在一个名为的数组中,以便: 如果--- 数组应如下所示: 我已经尝试了很多,并且总是有更多的迭代和/或在不同名称的情况下无法打印任何内容。 我的代码看起来像: 我也无法正确比较h1和h2的值。 非常感谢您的帮助,因为我对Ruby还很陌生,不幸的是,我的逻辑无法帮助我。 提

  • 寻找一种优雅的方式以特殊的方式合并两个散列数组: 如果名称关键字匹配,则结果必须包含< code>new_data的所有名称散列,仅包含< code>old_data的额外数据。 我的第一次尝试是这样的,但是它创建了一个额外的散列:

  • 问题内容: 我整个上午都在搜索,但是大多数合并示例仅基于一个键,而在多个键上却找不到任何东西。 pid = 111,sid = 6,eid = 123的值在x和y中都匹配,然后合并为一条记录。如果它们不匹配,只需将其原样带过来。 我想要的最终结果: 问题答案: 这是从元组中重新锁定:

  • 问题内容: 我有两个像下面的哈希图: 键不相同,但值相同,有时值也不相同。 我想找出与比较时不存在的值 但这使我从employeeMap中得到null。 您能帮我解决这个问题吗? 问候托尼 问题答案: 以下是完美运行的代码,比较失败的原因是映射值不同。 如果我们看到日期,则可以清楚地看到差异。 不同于 因为我将其存储为字符串。 谢谢你们的支持以及也投下反对票的人们。 :)托尼

  • 我有以下课程: