Reputation: 97
I have the following array and I want to convert it a hash with keys as age and values like the name of the person. Additionally, I want to make sure that folks of the same age belong to the same key.
ages = [ ['alpha', 20], ['beta',21], ['charlie',23], ['delta', 20] , ['gamma', 23]]
how do I convert the above into a hash like below?
eg - {20 => ['alpha','delta'] }
etc.
i have tried the following code but i am getting stuck beyond this point:
hash = Hash[ages.collect {|item| [item[1], item[0]]} ]
pp hash
thank you.
Upvotes: 0
Views: 250
Reputation: 26758
Yet another way to do this: Hash#transform_values with Enumerable#group_by
ages.
group_by(&:second).
transform_values { |entries| entries.map(&:first) }
# => {20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
Upvotes: 2
Reputation: 110665
ages.each_with_object({}) do |(str,x),h|
(h[x] ||= []) << str
end
#=> {20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
h[x] ||= []
expands to
h[x] = h[x] || []
If h
does not have a key x
this becomes
h[x] = nil || []
causing h[x]
to be set equal to an empty array, after which h[x] << str
is executed.
Expressing the block variables as |(str,x),h|
makes use of Ruby's array decomposition:
enum = ages.each_with_object({})
#=> #<Enumerator: [["alpha", 20], ["beta", 21], ["charlie", 23],
# ["delta", 20], ["gamma", 23]]:each_with_object({})>
(str,x),h = enum.next
#=> [["alpha", 20], {}]
str
#=> "alpha"
x #=> 20
h #=> {}
(h[x] ||= []) << str
#=> ["alpha"]
(str,x),h = enum.next
#=> [["beta", 21], {20=>["alpha"]}]
and so on.
Upvotes: 1
Reputation: 4440
One of the possible solutions is to use:
hash = ages.each_with_object(Hash.new {|h,k| h[k] = [] }) do |obj, res|
res[obj.last] << obj.first
end
=> {20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
Upvotes: 2
Reputation: 158
you can create the hash first and loop through the ages collecting members of similar ages into arrays.
hash = Hash.new{|h,k|h[k]=Array.new()}
ages.each do |age|
hash[age.last]<<age.first
end
p hash #{20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
Upvotes: 1