当唯一ID匹配时,将键值对添加到哈希数组

时间:2015-06-24 19:41:16

标签: arrays ruby hash

我有两个哈希数组

sent_array = [{:sellersku=>"0421077128", :asin=>"B00ND80WKY"},
{:sellersku=>"0320248102", :asin=>"B00WTEF9FG"}, 
{:sellersku=>"0324823180", :asin=>"B00HXZLB4E"}]

active_array = [{:price=>39.99, :asin1=>"B00ND80WKY"}, 
{:price=>7.99, :asin1=>"B00YSN9QOG"}, 
{:price=>10, :asin1=>"B00HXZLB4E"}]

我想循环遍历sent_array,并找到其中的值:asin等于:active_array中的asin1中的值,然后复制键&价值:price to sent_array。结果如下:

final_array = [{:sellersku=>"0421077128", :asin=>"B00ND80WKY", :price=>39.99},
{:sellersku=>"0320248102", :asin=>"B00WTEF9FG"}, 
{:sellersku=>"0324823180", :asin=>"B00HXZLB4E", :price=>10}]

我尝试了这个,但是我得到了一个TypeError - 没有将Symbol隐式转换为Integer(TypeError)

sent_array.each do |x|
 x.detect { |key, value| 
  if value == active_array[:asin1]
    x[:price] << active_array[:price]
  end
 }
end

3 个答案:

答案 0 :(得分:2)

出于效率和可读性的原因,首先在active_array上构建查找哈希是有意义的:

h = active_array.each_with_object({}) { |g,h| h[g[:asin1]] = g[:price] } 
  #=> {"B00ND80WKY"=>39.99, "B00YSN9QOG"=>7.99, "B00HXZLB4E"=>10}

我们现在只需逐步浏览sent_array,更新哈希值:

sent_array.each { |g| g[:price] = h[g[:asin]] if h.key?(g[:asin]) }
  #=> [{:sellersku=>"0421077128", :asin=>"B00ND80WKY", :price=>39.99},
  #    {:sellersku=>"0320248102", :asin=>"B00WTEF9FG"}, 
  #    {:sellersku=>"0324823180", :asin=>"B00HXZLB4E", :price=>10}] 

当然,从散列(h)中检索键值对比在散列数组中搜索键值对要快得多。

答案 1 :(得分:0)

这就是诀窍。迭代发送的数组并尝试在active_array中找到具有以下内容的记录:asin。如果您找到了什么,请设定价格并完成。

我认为您使用的代码检测/查找错误。你想要的那个方法是匹配的哈希,然后用它做一些事情。你试图在检测中做所有事情。

sent_array.each do |sent|
  item = active_array.find{ |i| i.has_value? sent[:asin] }
  sent[:price] = item[:price] if item
end

 => [{:sellersku=>"0421077128", :asin=>"B00ND80WKY", :price=>39.99}, {:sellersku=>"0320248102", :asin=>"B00WTEF9FG"}, {:sellersku=>"0324823180", :asin=>"B00HXZLB4E", :price=>10}] 

答案 2 :(得分:0)

我假设sent_arrayactive_array的第二个元素分别为asin和asin1 B00WTEF9FG。 (看到你的最终结果)

现在:

a = active_array.group_by{|a| a[:asin1]}
b = sent_array.group_by{|a| a[:asin]}
a.map { |k,v|
   v[0].merge(b[k][0])
}

#  => [{:price=>39.99, :asin1=>"B00ND80WKY", :sellersku=>"0421077128", :asin=>"B00ND80WKY"}, {:price=>7.99, :asin1=>"B00WTEF9FG", :sellersku=>"0320248102", :asin=>"B00WTEF9FG"}, {:price=>10, :asin1=>"B00HXZLB4E", :sellersku=>"0324823180", :asin=>"B00HXZLB4E"}] 

你为什么会遇到TypeError?

你在做active_array[:asin1]。记住active_array本身就是一个数组。除非你迭代它,否则你无法找到密钥。

您的方法的另一个问题是,您正在使用Hash#detect

  

find是根据each实施的。而each,当被召唤时   Hash,以2个元素的数组形式返回键值对   每。这就是find返回数组的原因。

source

detect也是如此。所以x.detect { |key, value| .. }不会像你期望的那样起作用。

没有假设的解决方案

a.map { |k,v|
   b[k] ? v[0].merge(b[k][0]) : v[0]
}.compact
# => [{:price=>39.99, :asin1=>"B00ND80WKY", :sellersku=>"0421077128", :asin=>"B00ND80WKY"}, {:price=>7.99, :asin1=>"B00YSN9QOG"}, {:price=>10, :asin1=>"B00HXZLB4E", :sellersku=>"0324823180", :asin=>"B00HXZLB4E"}] 

由于asin1 => "B00ND80WKY"没有匹配,因此无法从其他哈希中获取sellersku