patternrubyMinor
Combining two Arrays of hashes based on a hash key
Viewed 0 times
arrayscombininghashtwobasedhasheskey
Problem
I have two arrays of variable lengths:
For example, given this input:
I would like this result:
Here's what I came up with:
I looked at Array#zip, but it doesn't seem to take a condition. Is there a more idiomatic way to do this?
people1 and people2. I want to create an array of arrays where each inner array is a pair of elements from people1 and people2 The pairing should be based on a matching key. I'm using Ruby 2.2.0.For example, given this input:
people1 = [{ name: :jon, id: 1 }, { name: :jay, id: 3 }, { name: :ray, id: 5 }]
people2 = [{ name: :jon, id: 2 }, { name: :ray, id: 7 }]I would like this result:
pairs = [
[{ name: :jon, id: 1 }, { name: :jon, id: 2 }],
[{ name: :ray, id: 5 }, { name: :ray, id: 7 }]
]Here's what I came up with:
people1.collect do |p1|
if p2 = people2.find { |p2| p1[:name] == p2[:name] }
[p1, p2]
else
nil
end
end.compactI looked at Array#zip, but it doesn't seem to take a condition. Is there a more idiomatic way to do this?
Solution
First create a hash that maps names to the hashes for one list:
Filter the other list
This will only work properly if there are no duplicate names in each, but it is \$\mathcal{O}(n)\$ in the number of hashes.
people2_by_name = Hash[people2.map { |h| [h[:name], h] }]Filter the other list
people1.select { |h| people2_by_name.has_key?(h[:name]) }
.map { |h| [h, people2_by_name[h[:name]]] }This will only work properly if there are no duplicate names in each, but it is \$\mathcal{O}(n)\$ in the number of hashes.
Code Snippets
people2_by_name = Hash[people2.map { |h| [h[:name], h] }]people1.select { |h| people2_by_name.has_key?(h[:name]) }
.map { |h| [h, people2_by_name[h[:name]]] }Context
StackExchange Code Review Q#93015, answer score: 4
Revisions (0)
No revisions yet.