Reputation: 828
I have this nested array
array = [["Colorado", "Adams County"], ["Colorado", "Jefferson County"], ["California", "Amador"], ["California", "Tulare"]]
I am expecting this
{"Colorado" => ["Adams County", "Jefferson County"], "California" => ["Amador", "Tulare"]}
I tried these:
array.to_h
#=> {"Colorado"=>"Jefferson County", "California"=>"Tulare"}
b = Hash.new
array.uniq.map{|k,v| b[k] = v}
#=> {"Colorado"=>"Jefferson County", "California"=>"Tulare"}
array.uniq.map{|k,v| b[k] << v}
#=> Error
array.map{|k,v| b[k] = [v]}
#=> {"Colorado"=>["Jefferson CountyAdams CountyJefferson CountyAdams County"], "California"=>["TulareAmadorTulareAmador"]}`
How can I get the values as an array?
Upvotes: 2
Views: 816
Reputation: 11070
You can first call group_by
and then transform_values
(Ruby 2.4+):
hash = array.group_by(&:first)
# => {"Colorado"=>[["Colorado", "Adams County"], ["Colorado", "Jefferson County"]], "California"=>[["California", "Amador"], ["California", "Tulare"]]}
hash.transform_values! { |value_list| value_list.map(&:last) }
# => {"Colorado"=>["Adams County", "Jefferson County"], "California"=>["Amador", "Tulare"]}
If your ruby doesn't have transform_values
, you can just map!
:
hash = array.group_by(&:first)
hash.each_value do |value_list|
value_list.map!(&:last)
end
# => {"Colorado"=>["Adams County", "Jefferson County"], "California"=>["Amador", "Tulare"]}
Upvotes: 4
Reputation: 121010
[["Colorado", "Adams County"], ["Colorado", "Jefferson County"],
["California", "Amador"], ["California", "Tulare"]].
each_with_object(Hash.new { |h, k| h[k] = [] }) do |(k, v), h|
h[k] << v
end
#⇒ {
# "California" => [
# [0] "Amador",
# [1] "Tulare"
# ],
# "Colorado" => [
# [0] "Adams County",
# [1] "Jefferson County"
# ]
# }
Or, for Ruby 2.4+:
[["Colorado", "Adams County"], ["Colorado", "Jefferson County"],
["California", "Amador"], ["California", "Tulare"]].
group_by(&:shift).transform_values(&:flatten)
Upvotes: 1
Reputation: 8467
It looks like you want Enumerable#group_by
to regroup the array of arrays by the first element.
array
.group_by { |k, _| k }
.each_value { |a| a.map! { |_, v| v } } # => {"Colorado"=>["Adams County", "Jefferson County"], "California"=>["Amador", "Tulare"]}
Upvotes: 1