From: Ryan Davis Date: 2009-10-02T04:21:49+09:00 Subject: Re: how do you do this On Oct 1, 2009, at 05:34 , Ilan Berci wrote: > George George wrote: >> Given an array of strings e.g. >> x = ["abc","abcde" "def","xyzwj"] and of different lengths, >> how can you efficiently create new arrays of strings which are of the >> same length. for example the above array can be transformed into >> >> x1 = ["abc","def"] >> x2 = ["abcde","xyzwj"] >> >> Thank you. > > y = {} > x.each do |v| > y[v.length] || = [] > y[v.length] << v > end > y.values > > or if you prefer less lines.. > > x.inject({}) do |h, v| > (y[v.length] || = []) << v > h > end.values Syntax error in both cases. It needs to be "||=", not "|| =". Well... inject ALWAYS loses, but fanboys sure seems to like it for no good reason. By using better names and the right tool for the job, this becomes a LOT more readable, maintanable, and faster all in one fell swoop: by_length = Hash.new { |h,k| h[k] = [] } strings.each do |string| by_length[string.length] << string end by_length.values # I think this part is a mistake, but I wanted to match I think the readability is more important than speed by a long shot... But just in case you're not convinced, check out the benchmarks: % ./blah.rb 10000 # of iterations = 10000 user system total real null_time 0.000000 0.000000 0.000000 ( 0.001370) mine 7.790000 0.050000 7.840000 ( 7.869737) yours-inject 15.170000 0.050000 15.220000 ( 15.554334) yours-each 11.850000 0.100000 11.950000 ( 12.013553) inject is twice as slow as mine. stop using it.