3

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.

3 Answers 3

3

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!

Sign up to request clarification or add additional context in comments.

2 Comments

Interesting - thanks Pawel! Do you also know a function that lets me find just the matching object from scores given an ID?
Actually, this is what find (from Enumerable module, which is included in Array) does. You should go with: scores.find { |element| element[:id] == 123 }. Check documentation for more examples. Hope that helps!
1

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

1 Comment

I like your solution, but would prefer a2.each_with_object({}) { |g,h| h.update(g[id] => g) }, as it doesn't mutate a2 and IMO it reads better.
1

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?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.