Reputation: 8096
If you have an array of objects with two attributes, a and b, e.g.
$ irb
2.1.3 :001 > D = Struct.new(:a, :b)
=> D
2.1.3 :002 > data = [] << D.new('e', 'f') << D.new('g', 'h') << D.new('e', 'i') << D.new('j', 'h')
=> [#<struct D a="e", b="f">, #<struct D a="g", b="h">, #<struct D a="e", b="i">, #<struct D a="j", b="h">]
And want to produce from that a hash where the attribute a is the key and attribute b is a collection of values, e.g.
{"e"=>["f", "i"], "g"=>["h"], "j"=>["h"]}
What is a simple way to do that in Ruby?
(I've shared my answer that uses each_with_object
, but maybe there is a simpler or clearer way.)
Upvotes: 0
Views: 218
Reputation: 5773
Another way of doing it is
1.9.3-p327 :023 > hash = data.inject(Hash.new {|h, k| h[k] = []}) {|h, i| h[i.a] << i.b; h}
=> {"e"=>["f", "i"], "g"=>["h"], "j"=>["h"]}
Upvotes: 0
Reputation: 8096
This can be done with each_with_object:
2.1.3 :003 > data.each_with_object({}) {|p, h| (h[p.a] ||= []) << p.b}
=> {"e"=>["f", "i"], "g"=>["h"], "j"=>["h"]}
Upvotes: 1