2015-03-26 7 views
0

Эй, ребята, если у меня есть массив, содержащий хэшей, как так:Объединение массивов, содержащих хэши внутри - Руби

random_arary = [ 
    {number: 123, x: 2}, 
    {number: 123, y: 7}, 
    {number: 123, z: 2}, 
    {number: 456, a: 3}, 
    {number: 456, b: 4}, 
    {number: 456, c: 0} 
] 

и я хочу, чтобы объединить все хэши в только два хэшей так:

random_array= 
     [ 
      {time: 123, x: 2, y: 7, z: 2}, 
      {time: 456, a: 3, b: 4, c: 0}, 
     ] 

Каким будет хороший способ приблизиться к этому?

EDIT: чтобы сделать мой вопрос более ясным, я хочу сгруппировать все хеши с номером k.v «число: 123» вместе и все хеши с номером k.v «число: 456» вместе.

Таким образом, все хэши, начинающиеся с пары значений «число: 123», объединяются в один хеш, и все хэши с ключом «число: 456» объединяются в один хеш.

+1

Будет ли всегда 6 хешей? Вы всегда хотите разбить их пополам? Имеет ли значение то, что входит в финальный хеш? Будет ли всегда 4 вещи в хэше и будет ли первое всегда «время» с 3-мя символами после него? – Beartech

+1

Каковы критерии для создания двух хэшей? – vgoff

+1

Да, что сказал @Beartech. :) – vgoff

ответ

4
random_array.group_by {|x|x[:number]}.values.map {|x|x.reduce(:merge)} 
# => [ 
# {:number=>123, :x=>2, :y=>7, :z=>2}, 
# {:number=>456, :a=>3, :b=>4, :c=>0} 
# ] 

Или, в том числе подмены ключа :number для :time:

def transform(arr) 
    groups = arr.group_by {|x|x[:number]}.values.map {|x|x.reduce(:merge)} 
    groups.each { |x| x[:time] = x[:number]; x.delete(:number) } 
end 
+0

Ницца - хотя вы не удовлетворяли, казалось бы, произвольным переименованием ': number' to': time' (!) – Shadwell

+0

@Shadwell: да, хороший глаз - обновлен. – maerics

0

Один из способов заключается в использовании форму Hash#update (ака merge!), который использует блок для определения значений ключей, присутствуют в обоих хешах:

random_array.each_with_object({}) do |g,h| 
    h.update(g[:number]=>g.reject { |k,_| k==:number }) { |_,o,n| o.update(n) } 
end.map { |nbr,h| h.merge(:time=>nbr) } 
    #=> [{:x=>2, :y=>7, :z=>2, :time=>123}, {:a=>3, :b=>4, :c=>0, :time=>456}] 
Смежные вопросы