Превращение хеша массивов в массив хешей в Ruby

Я только изучил vi, когда я начал работать на ISP где сценарии для редактирования доменов только открытый vi на терминале. У меня не было выбора, кроме как изучить его, но я никогда не сожалел о нем.

Короче говоря, помещает себя в ситуацию, где у Вас нет выбора, кроме как изучить его.

11
задан Julien Genestoux 29 October 2009 в 00:42
поделиться

5 ответов

Это решение работает с произвольным количеством значений (val1, val2 ... valN):

{:a => ["val1", "val2"], :b => ["valb1", "valb2"]}.inject([]){|a, (k,vs)| 
  vs.each_with_index{|v,i| (a[i] ||= {})[k] = v} 
  a
}
# => [{:a=>"val1", :b=>"valb1"}, {:a=>"val2", :b=>"valb2"}]

[{:a=>"val1", :b=>"valb1"}, {:a=>"val2", :b=>"valb2"}].inject({}){|a, h| 
  h.each_pair{|k,v| (a[k] ||= []) << v}
  a
}
# => {:a=>["val1", "val2"], :b=>["valb1", "valb2"]}
12
ответ дан 3 December 2019 в 05:13
поделиться

Это будет работать при условии, что все массивы в исходном хеш-коде имеют одинаковый размер:

hash_array = hash.first[1].map { {} }
hash.each do |key,arr|
  hash_array.zip(arr).each {|inner_hash, val| inner_hash[key] = val}
end
0
ответ дан 3 December 2019 в 05:13
поделиться
m = {}
a,b = Array(h).transpose
b.transpose.map { |y| [a, y].transpose.inject(m) { |m,x| m.merge Hash[*x] }}
1
ответ дан 3 December 2019 в 05:13
поделиться

Вы можете использовать inject для создания массива хэшей.

hash = { :a => ["val1", "val2"], :b => ["valb1", "valb2"] }
array = hash.inject([]) do |pairs, pair|
  pairs << { pair[0] => pair[1] }
  pairs
end
array.inspect # => "[{:a=>["val1", "val2"]}, {:b=>["valb1", "valb2"]}]"

В документации Ruby есть еще несколько примеров работы с inject .

0
ответ дан 3 December 2019 в 05:13
поделиться

Давайте внимательно посмотрим, в какую структуру данных мы пытаемся преобразовать:

#Format A
[
 ["val1", "val2"],          :a
 ["valb1", "valb2"],        :b 
 ["valc1", "valc2"]         :c 
]
#Format B
[ :a        :b       :c
 ["val1", "valb1", "valc1"],
 ["val2", "valb2", "valc3"]
]

Нетрудно найти Формат B является транспонированным из Формат A существенно, тогда мы можем придумать следующее решение:

h={:a => ["vala1", "vala2"], :b => ["valb1", "valb2"], :c => ["valc1", "valc2"]}
sorted_keys =  h.keys.sort_by {|a,b| a.to_s <=> b.to_s}

puts sorted_keys.inject([])  {|s,e| s << h[e]}.transpose.inject([])   {|r, a| r << Hash[*sorted_keys.zip(a).flatten]}.inspect
#[{:b=>"valb1", :c=>"valc1", :a=>"vala1"}, {:b=>"valb2", :c=>"valc2", :a=>"vala2"}]
1
ответ дан 3 December 2019 в 05:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: