Ruby массив хэш. group_by и изменить в одной строке
У меня есть массив хэшей, что-то вроде
[ {:type=>"Meat", :name=>"one"},
{:type=>"Meat", :name=>"two"},
{:type=>"Fruit", :name=>"four"} ]
и я хочу преобразовать его в это
{ "Meat" => ["one", "two"], "Fruit" => ["Four"]}
Я пробовал group_by
, но потом получил это
{ "Meat" => [{:type=>"Meat", :name=>"one"}, {:type=>"Meat", :name=>"two"}],
"Fruit" => [{:type=>"Fruit", :name=>"four"}] }
а затем я не могу изменить его, чтобы оставить только имя, а не полный хеш. Мне нужно сделать это в одной строке, потому что для grouped_options_for_select
в форме Rails.
Ответы
Ответ 1
array.group_by{|h| h[:type]}.each{|_, v| v.replace(v.map{|h| h[:name]})}
# => {"Meat"=>["one", "two"], "Fruit"=>["four"]}
Следующее предложение steenslag:
array.group_by{|h| h[:type]}.each{|_, v| v.map!{|h| h[:name]}}
# => {"Meat"=>["one", "two"], "Fruit"=>["four"]}
Ответ 2
В одной итерации над исходным массивом:
arry.inject(Hash.new([])) { |h, a| h[a[:type]] += [a[:name]]; h }
Ответ 3
array = [{:type=>"Meat", :name=>"one"}, {:type=>"Meat", :name=>"two"}, {:type=>"Fruit", :name=>"four"}]
array.inject({}) {|memo, value| (memo[value[:type]] ||= []) << value[:name]; memo}
Ответ 4
Я бы сделал следующее:
hsh =[{:type=>"Meat", :name=>"one"}, {:type=>"Meat", :name=>"two"}, {:type=>"Fruit", :name=>"four"}]
p Hash[hsh.group_by{|h| h[:type] }.map{|k,v| [k,v.map{|h|h[:name]}]}]
# >> {"Meat"=>["one", "two"], "Fruit"=>["four"]}
Ответ 5
Использование ActiveSuport Hash#transform_values
:
array.group_by{ |h| h[:type] }.transform_values{ |hs| hs.map{ |h| h[:name] } }
#=> {"Meat"=>["one", "two"], "Fruit"=>["four"]}