2015-06-04 39 views
2

我有对象的具有独特的ID的数组:合并对象的两个阵列中的Ruby

[{id: 1, score: 33}, {id: 23, score: 50}, {id:512, score: 27}, ...] 

我也有用户记录具有匹配的ID的数组。用户记录有“名称”但不是“得分”:

[{id: 1, name: "Jon"}, {id: 23, name: "Tom"}, {id: 512, name: "Joey"}, ...] 

如何创建一个包含每个ID,名称和分数的单个数组?

[{id: 1, name: "Jon", score: 33}, {id: 23, name: "Tom", score: 50}, {id: 512, name: "Joey", score: 27}, ...] 

我试过mergecombinefilter等,但还没有找到Ruby的功能来做到这一点。

回答

3

假设在users总是纪录,从相应scores:id

scores = [{id: 1, score: 33}, {id: 23, score: 50}, {id:512, score: 27}] 
users = [{id: 1, name: "Jon"}, {id: 23, name: "Tom"}, {id: 512, name: "Joey"}] 

scores = scores.map { |score| score.merge(users.find { |user| user[:id] == score[:id] }) } 
# => [{:id=>1, :score=>33, :name=>"Jon"}, {:id=>23, :score=>50, :name=>"Tom"}, {:id=>512, :score=>27, :name=>"Joey"}] 

希望将你放在正确的方向!

+0

有趣的 - 谢谢帕维尔!你是否也知道一个函数,可以让我从给定ID的分数中找到匹配的对象? –

+1

实际上,这是['find'](http://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-find)(来自'Enumerable'模块,它包含在[ 'Array'](http://ruby-doc.org/core-2.2.0/Array.html))。你应该使用:'scores.find {| element |元素[:id] == 123}'。检查更多示例的文档。希望有所帮助! –

1

您可以使用中间散列。

hsh = Hash[ a1.map {|h| [h[:id], h[:score]]} ] 
# => {1=>33, 23=>50, 512=>27} 
a2.map {|h| h[:score] = hsh[h[:id]]; h} 
# => [{:id=>1, :name=>"Jon", :score=>33}, {:id=>23, :name=>"Tom", :score=>50}, {:id=>512, :name=>"Joey", :score=>27}] 
+0

我喜欢你的解决方案,但宁愿'a2.each_with_object({}){| g,h | h.update(g [id] => g)}',因为它不会改变'a2'和IMO,它会读得更好。 –

0

如果,作为例子,scores[i][:id] = users[i][:id]所有i,并且使用的是V1.9 +(其中键插入顺序保持不变),你可以写:

scores.zip(users).each_with_object({}) do |(sh,uh),h| 
    h.update(sh).update(uh) 
end 

我会用这个?你会?