From: Wes Bailey Date: 2010-06-11T14:22:23+09:00 Subject: Re: Split an array of object by first letter ----- "Phrogz" wrote: > On Jun 10, 1:45 pm, Joel VanderWerf wrote: > > > I have an array of brands and I need to split this array by brand > name > > > first letter. How can I do that? > > > > ["fz", "yt", "fu", "za", "zw", "yo", "zb"].group_by {|s|s[0,1]} > > => {"y"=>["yt", "yo"], "z"=>["za", "zw", "zb"], "f"=>["fz", "fu"]} > > Joel is right on. My addition below shows that (a) this works not > just > for two-letter words, and (b) if you're using Ruby 1.9, you can use a > slightly simpler syntax: > > > [ "foo", "bar", "flim", "bork", "cow" ].group_by{ |name| name[0] } > #=> {"f"=>["foo", "flim"], "b"=>["bar", "bork"], "c"=>["cow"]} > > Note that case matters, but you can make it irrelevant: > > [ "foo", "bar", "Flim", "bork" ].group_by{ |name| name[0] } > #=> {"f"=>["foo"], "b"=>["bar", "bork"], "F"=>["Flim"]} > > [ "foo", "bar", "Flim", "bork" ].group_by{ |name| name[0].downcase } > #=> {"f"=>["foo", "Flim"], "b"=>["bar", "bork"]} > > And finally, just for the love of monkeypatching: > > class String > def first_letter > self[0].downcase > end > end > > class Array > def alphabetical > Hash[ group_by{|s|s.first_letter}.sort_by{|c,a|c} ] > end > end > > [ "foo", "bar", "Flim", "bork" ].alphabetical > #=> {"b"=>["bar", "bork"], "f"=>["foo", "Flim"]} Anyone remember %w or do you all love quotes so much :P Since the poster didn't specify whether they were on ruby 1.8 or 1.9: irb(main):021:0> %w/foo bar Film bork Baz/.inject( {} ) { |h,v| k = v[0,1].downcase; a = h[k] || []; h.merge( { k => a << v } ) } => {"b"=>["bar", "bork", "Baz"], "f"=>["foo", "Film"]}