Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I combine array values with array of hashes?

Tags:

ruby

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.

like image 781
sberry Avatar asked Dec 07 '22 07:12

sberry


2 Answers

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.

like image 155
the Tin Man Avatar answered Jan 15 '23 09:01

the Tin Man


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}]
like image 40
toro2k Avatar answered Jan 15 '23 09:01

toro2k