2013-06-21 4 views
4

У меня есть массив хэшей:Как объединить значения массива с массивом хэшей?

[{:foo => 1, :bar => 2}, {:foo => 2, :bar => 4} ...] 

и массив целых чисел:

[3, 6] 

Я хочу объединить значения из массива целых чисел и хэшей в конечном итоге что-то вроде:

[{:foo => 1, :bar => 2, :baz => 3}, {:foo => 2, :bar => 4, :baz => 6}] 

В настоящее время я делаю это:

myArrayOfHashes.each_with_index |myHash, index| 
    myHash[:baz] = myArrayOfIntegers[index] 
end 

Это правильный подход?

Я представлял себе более функциональный подход, когда я повторяю оба массива одновременно, как-то используя zip + map.

+0

Это не нужно повторно указать вы хотите сделать это с помощью Ruby. Теги, которые вы установили, расскажут нам язык, функции или библиотеки. –

+0

Да, хороший звонок @theTinMan. Просто не уверен, что любимые теги используются человеком, который мог бы ответить. Но, отметил в будущем. – sberry

+1

Если кто-то пытается ответить, кто * не обратил внимания на теги, шансы действительно хороши, они получат много голосов, не обратив внимания. Они не повторят этого. –

ответ

6

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 

Какие результаты в:

[{:foo=>1, :bar=>2, :baz=>3}, {:foo=>2, :bar=>4, :baz=>6}] 

zip является хорошим инструментом для этого, но map не будет действительно покупать много, по крайней мере, ничего такого, что вы не можете сделать как легко с each в этом случае.

Кроме того, не называйте переменные с помощью CamelCase, например myArrayOfHashes, вместо этого используйте snake_case, например ary_of_hashes. Мы используем CamelCase для имен классов. Технически мы можем использовать смешанный случай для переменных, но по соглашению мы этого не делаем.

И возможно использовать each_with_index, но это приводит к неудобному коду, потому что это заставляет вас использовать индекс в [3, 6]. Пусть zip присоединяются к соответствующим элементам обоих массивов, и у вас будет все необходимое для массажа хэша.

+0

Что такое 'pp'? ... –

+0

Попробуйте' ri Kernel.pp' из командной строки или проверьте http://www.ruby-doc.org/stdlib-2.0/libdoc/pp/rdoc/index.html –

+0

Очень хорошо. Я решил, что могу использовать zip здесь и делать именно это, не уверенный, какую ошибку я делал, когда я пробовал это раньше. – sberry

6

map полезно, если вы хотите оставить исходные объекты нетронутыми:

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

В соответствии с образцом кода в вопросе, это должно быть 'a.zip (b) .each {| h, i | часupdate (baz: i)} 'вместо того, чтобы создавать новый хэш и оставлять' a' неизменным. –

+0

Возможно, я слишком много думал о том, чтобы использовать карту, потому что похоже, что это может быть необязательно. + 1 все же. – sberry

3
array_of_hashes.each { |hash| hash.update baz: array_of_integers.shift } 
+1

Хорошо (+1), но он уничтожает 'array_of_integers'. –

+0

Предостережение с 'array_of_integers.shift'. Это будет разрушительно. –

+0

Правильно, чтобы сохранить массив целых чисел, сначала нужно вызвать 'array_of_integers.dup'. –