From: 7stud -- Date: 2009-09-11T09:42:40+09:00 Subject: Re: populating a hash from an array using inject Glenn Jackman wrote: > I was looking at this problem on Stack Overflow (this one: > http://stackoverflow.com/questions/1405657/reorganizing-ruby-array-into-hash > > The question is how to "convert" an array of objects into a hash. > > Consider this code: > > require 'pp' > p RUBY_VERSION > > Product = Struct.new(:name, :category) > products = [ > ['Apple','Golden Delicious'], > ['Apple','Granny Smith'], > ['Orange','Navel'] > ].collect {|cat, name| Product.new(name, cat)} > > foo = products.inject({}) {|h,p| h[p.category] ||= []; h[p.category] > << p; h} > pp foo > > bar = products.inject(Hash.new([])) {|h,p| h[p.category] << p; h} > pp bar > > baz = products.inject(Hash.new([])) {|h,p| h[p.category] += p; h} > pp baz > > It outputs: > > "1.8.7" > {"Orange"=>[#], > "Apple"=> Even though it is not very well written, if you read the documentation on creating hashes with default values: $ ri Hash.new -------------------------------------------------------------- Hash::new Hash.new => hash Hash.new(obj) => aHash Hash.new {|hash, key| block } => aHash ------------------------------------------------------------------------ Returns a new, empty hash. If this hash is subsequently accessed by a key that doesn't correspond to a hash entry, the value returned depends on the style of +new+ used to create the hash. In the first form, the access returns +nil+. If _obj_ is specified, this single object will be used for all _default values_. If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block's responsibility to store the value in the hash if required. h = Hash.new("Go Fish") h["a"] = 100 h["b"] = 200 h["a"] #=> 100 h["c"] #=> "Go Fish" # The following alters the single default object h["c"].upcase! #=> "GO FISH" h["d"] #=> "GO FISH" h.keys #=> ["a", "b"] ----------------------------------------------------------- The key line is: ***8It is the block's responsibility to store the value in the hash if required.*** Because your block does not assign the array to a hash key, the array is discarded. -- Posted via http://www.ruby-forum.com/.