Don P
Don P

Reputation: 63788

Merge two arrays of objects in Ruby

I have an array of objects with unique IDs:

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

I also have an array of User records with matching IDs. The user records have "name" but not "score":

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

How can I create a single array with each id, name, and score?

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

I tried merge, combine, filter, etc but haven't found the Ruby function to accomplish this.

Upvotes: 3

Views: 2235

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110755

If, as in the example, scores[i][:id] = users[i][:id] for all i, and you are using v1.9+ (where key insertion order is maintained), you could write:

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

Would I use this? Would you?

Upvotes: 1

Santhosh
Santhosh

Reputation: 29174

You can use an intermediate Hash.

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}]

Upvotes: 1

Paweł Dawczak
Paweł Dawczak

Reputation: 9649

Assuming that in users there is always record with corresponding :id from scores:

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"}]

Hope that puts you in proper direction!

Upvotes: 3

Related Questions