模拟哈希之间的连接



我有两个哈希数组,它们模拟数据库中的两个表,第一个哈希中的一个键引用第二个哈希中的单独命名的键,示例如下:

cars = [ { id: 1, color: 'red', owner_id: 1 }, { id: 2, color: 'black', owner_id: 1 } ]
owners = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]

我想尝试在这两个哈希上完成"连接",从而产生一个新的哈希数组,以便owners的键和值将合并到任何cars哈希中,其中汽车的:owner_id与车主的:id相匹配。所以在上面的示例中,结果将如下所示:

[ { id: 1, color: 'red', owner_id: 1, name: 'Alice' }, { id: 2, color: 'black', owner_id: 1, name: 'Alice' } ]

有人对我如何实现这一目标有任何想法吗?谢谢!

[编辑] 更新以澄清我希望将结果放置在新的哈希数组中,而不是改变任何一个原始数组。

def join(referers, referees, on_referer, on_referee)
  referers.map do |record|
    referees.find do |referee_record|
      record[on_referer] == referee_record[on_referee]
    end.merge(record)
  end
end
cars = [ { id: 1, color: 'red', owner_id: 1 }, { id: 2, color: 'black', owner_id: 1 } ]
owners = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]
join(cars, owners, :owner_id, :id)
  # => [{:id=>1, :name=>"Alice", :color=>"red", :owner_id=>1},
  #     {:id=>2, :name=>"Alice", :color=>"black", :owner_id=>1}]

编辑:我刚刚注意到,cars中的关键:owner_id要与owners中的:id相匹配。我以为汽车的关键:id是匹配的。我将保持我的答案不变,考虑到修改是微不足道的,如果匹配是相同的键名,可能会更容易遵循。

假设:

  • 你想修改(改变(cars;和
  • 对于owners的每个元素h都有一个cars的元素gh[:id] == g[:id]

只是

owners.each { |h| cars.find { |g| g[:id] == h[:id] }.update(h) }
cars #=> [{:id=>1, :color=>"red", :owner_id=>1, :name=>"Alice"},
     #    {:id=>2, :color=>"black", :owner_id=>1, :name=>"Bob"}] 

另一方面,如果:

  • 您不希望cars
  • 对于owners h的给定元素,可能没有h[:id]==g[:id]carsg元素
  • 你只是想提高效率,

您可以先为键值为 :idcarsowners创建哈希。

假设:

owners = [ { id: 3, name: 'Alice' }, { id: 2, name: 'Bob' } ]

我们可以为owners创建一个哈希:

owners_by_id = owners.each_with_object({}) { |g,h| h.update(g[:id]=>g) }
  #=> {3=>{:id=>3, :name=>"Alice"}, 2=>{:id=>2, :name=>"Bob"}} 

然后写:

cars.map do |h|
  g = {}.merge(h)
  id = g[:id]
  g.update(owners_by_id[id]) if owners_by_id.key?(id)
  g
end
  #=> [{:id=>1, :color=>"red", :owner_id=>1},
  #    {:id=>2, :color=>"black", :owner_id=>1, :name=>"Bob"}] 

假设数组中相同位置的哈希对应于:

[cars, owners].transpose.map{|h1, h2| h1.merge(h2)}

否则,你的例子是不好的。

最新更新