根据键值匹配来自两个单独数组的对象

时间:2018-11-06 20:37:03

标签: ruby

我有两个数组。一个充满客户信息对象,另一个充满保险索赔对象。

customer = [{"Last Name":"lastname", "First Name":"firstname", "ID":"6583142"}]

claim = [{"ID"=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}]

目标是使每个索赔与客户匹配。我知道如何查看另一方是否存在ID,但是如何将两者关联?我认为将匹配的声明放到其他地方是没有道理的,因为在下一部分中,无论是否匹配,都需要接受或拒绝每个声明。

3 个答案:

答案 0 :(得分:1)

如果您要查找的是伪数据库(例如搜索)。

我在集合中使用复数形式:

customers = [{"Last Name": "lastname", "First Name": "firstname", "ID": "6583142"}]
claims = [{"ID"=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}]

Claim有一个客户,因此首先按索赔编号查找索赔,然后寻找其客户:

claim_number = "123214"
claim = claims.detect { |h| h["number"] == claim_number }
customer = customers.detect { |h| h[:"ID"] == claim["ID"] }
#=> {:"Last Name"=>"lastname", :"First Name"=>"firstname", :ID=>"6583142"}

客户有很多索赔,因此,给定客户ID,找到所有索赔:

customer_id = "6583142"
p all_claim_by_customer = claims.select { |h| h["ID"] == customer_id }
#=> [{"ID"=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}]

我建议使用符号作为散列的键。

答案 1 :(得分:1)

customers = [{ "Last Name":"Hardplace",  "First Name":"Rockina", "ID":"6583142" },
             { "Last Name":"Bebblebrox", "First Name":"Zaphod",  "ID":"6583143" }]

claims =    [{ "ID"=>"6583143", "number"=>"123215", "start_date"=>"2018-10-04" },
             { "ID"=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03" }]

def by_id(arr)
  arr.each_with_object({}) { |g,h| h[g[:ID]] = g }
end

customers_by_id = by_id(customers)
  #=> {"6583142"=>{:"Last Name"=>"Hardplace", :"First Name"=>"Rockina", :ID=>"6583142"},
  #    "6583143"=>{:"Last Name"=>"Bebblebrox", :"First Name"=>"Zaphod", :ID=>"6583143"}}
adj_claims = claims.map { |h| h.transform_keys { |k| k == "ID" ? :ID : k } }
  #=> [{:ID=>"6583143", "number"=>"123215", "start_date"=>"2018-10-04"},
  #    {:ID=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}]
claims_by_id = by_id(adj_claims)
  #=> {"6583143"=>{:ID=>"6583143", "number"=>"123215", "start_date"=>"2018-10-04"},
  #    "6583142"=>{:ID=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}}

给出一个索赔ID,例如"6583142",则客户和索赔信息包含在散列中:

customers_by_id["6583142"]
  #=> {:"Last Name"=>"Hardplace", :"First Name"=>"Rockina", :ID=>"6583142"}

claims_by_id["6583142"]
  #=> {:ID=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}

如果需要,可以合并具有相同ID的成对散列,但这并不是必须的。

customers_by_id.keys.each_with_object({}) { |k,h|
  h[k] = customers_by_id[k].merge(claims_by_id[k]) }
  #=> {"6583142"=>{:"Last Name"=>"Hardplace", :"First Name"=>"Rockina",
  #                :ID=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"},
  #    "6583143"=>{:"Last Name"=>"Bebblebrox", :"First Name"=>"Zaphod",
  #                :ID=>"6583143", "number"=>"123215", "start_date"=>"2018-10-04"}}

需要计算adj_claims,因为ID由customers中的符号和claims中的字符串表示。参见Hash#transform_keys。它是adj_claims中的符号。

答案 2 :(得分:0)

您需要执行以下操作:

customer = [{"Last Name" => "lastname", "First Name" => "firstname", "ID" => "6583142"}]
claim = [{"ID"=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}]

# Get all uniq ids
ids = (claim + customer).map {|object| object['ID']}.uniq

# Find claims and customers for every id
merged_data = ids.map do |id| 
    {
        id: id, 
        claims: claim.select{|claim| claim['ID'] == id}, 
        customers: customer.select{|customer| customer['ID'] == id}
    }
end

结果将是:

[{
  :id=>"6583142", 
  :claims=>[{"ID"=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03"}], 
  :customers=>[{"Last Name"=>"lastname", "First Name"=>"firstname", "ID"=>"6583142"}]
}]

此外,如果对于每个ID您只有一个索取权并且只有一个客户,您可以将其合并:

ids.map do |id|
    claim_hash = claim.select{|claim| claim['ID'] == id}.first
    customer_hash = customer.select{|customer| customer['ID'] == id}.first
    claim_hash.merge customer_hash
end
[{"ID"=>"6583142", "number"=>"123214", "start_date"=>"2018-10-03", "Last Name"=>"lastname", "First Name"=>"firstname"}]