Reputation: 131968
I have an array of hashes:
[{:foo => 1, :bar => 2}, {:foo => 2, :bar => 4} ...]
And an array of integers:
[3, 6]
I want combine the values from the integer array and the hashes to end up with something like:
[{:foo => 1, :bar => 2, :baz => 3}, {:foo => 2, :bar => 4, :baz => 6}]
I am currently doing this:
myArrayOfHashes.each_with_index |myHash, index|
myHash[:baz] = myArrayOfIntegers[index]
end
Is that the right approach?
I was imagining a more functional approach where I iterate over both arrays simultaneously, like something using zip
+ map
.
Upvotes: 4
Views: 163
Reputation: 19230
map
is useful when you want to leave the original objects intact:
a = [{:foo => 1, :bar => 2}, {:foo => 2, :bar => 4}]
b = [3,6]
a.zip(b).map { |h, i| h.merge(baz: i) }
# => [{:foo=>1, :bar=>2, :baz=>3}, {:foo=>2, :bar=>4, :baz=>6}]
a.inspect
# => [{:foo=>1, :bar=>2}, {:foo=>2, :bar=>4}]
Upvotes: 6
Reputation: 12578
array_of_hashes.each { |hash| hash.update baz: array_of_integers.shift }
Upvotes: 3
Reputation: 160553
Try:
require 'pp'
ary_of_hashes = [{:foo => 1, :bar => 2}, {:foo => 2, :bar => 4}]
[3, 6].zip(ary_of_hashes).each do |i, h|
h[:baz] = i
end
pp ary_of_hashes
Which results in:
[{:foo=>1, :bar=>2, :baz=>3}, {:foo=>2, :bar=>4, :baz=>6}]
zip
is a good tool for this, but map
won't really buy much, at least nothing that you can't do as easily with each
in this case.
Also, don't name variables using CamelCase like myArrayOfHashes
, instead use snake_case, like ary_of_hashes
. We use CamelCase for class names. Technically we can used mixed case for variables, but by convention we don't do that.
And, it's possible to use each_with_index
, but it results in awkward code, because it forces you to use an index into [3, 6]
. Let zip
join the respective elements of both arrays and you'll have everything you need to massage the hash.
Upvotes: 6