Например, у меня есть массив отдельных хэшмассива хэш хэш
a = [{a: :b}, {c: :d}]
Что лучший способ, чтобы преобразовать его в это?
{a: :b, c: :d}
Например, у меня есть массив отдельных хэшмассива хэш хэш
a = [{a: :b}, {c: :d}]
Что лучший способ, чтобы преобразовать его в это?
{a: :b, c: :d}
Вы можете использовать
a.reduce Hash.new, :merge
, который дает непосредственно
{:a=>:b, :c=>:d}
Обратите внимание, что в случае столкновения порядок важен. Последних хэши переопределять предыдущие отображения, смотри, например:
[{a: :b}, {c: :d}, {e: :f, a: :g}].reduce Hash.new, :merge # {:a=>:g, :c=>:d, :e=>:f}
Эти две строки эквивалентны:
total_hash = hs.reduce({}) { |acc_hash, hash| acc_hash.merge(hash) }
total_hash = hs.reduce({}, :merge)
Обратите внимание, что Hash#merge
создает новый хэш на каждой итерации, который может быть проблемой, если вы строите большой хеш. В этом случае используйте update
вместо:
total_hash = hs.reduce({}, :update)
Альтернативный подход будет конвертировать хэши парам, а затем построить окончательный хэш:
total_hash = hs.flat_map(&:to_a).to_h
Вы можете использовать .inject
:
a.inject(:merge)
#=> {:a=>:b, :c=>:d}
Что инициирует новый хэш на каждой итерации из двух объединенных. Чтобы избежать этого, вы можете использовать разрушительный :merge!
(или :update
, что то же самое):
a.inject(:merge!)
#=> {:a=>:b, :c=>:d}
Попробуйте
a.inject({}){|acc, hash| acc.merge(hash)} #=> {:a=>:b, :c=>:d}
'Hash.new', или как друзья, как в позвоните ему, '{}' :-) Насколько мне нравится чистое функциональное решение, обратите внимание, что 'merge' создаст новый хэш на каждой итерации; вместо этого мы можем использовать 'update' (это не испортит хеши ввода, это важный момент):' hs.reduce ({},: update) ' – tokland
Красиво сделано – Aeramor
@tokland, опубликуйте свой комментарий как отдельный ответ - он должен получить больше видимости – Jason