From: Phrogz Date: 2009-10-31T08:00:12+09:00 Subject: Re: two stage array sorting On Oct 30, 11:17 am, John W Higgins wrote: > [Note:  parts of this message were removed to make it a legal post.] > > Morning Tim, > > > > > > On Fri, Oct 30, 2009 at 9:35 AM, Tim Ferrell wrote: > > > I have an array of strings like so: > > >  Tuesday 12:00 AM > >  Sunday 9:00 AM > >  Tuesday 3:00 PM > >  Friday 7:30 AM > >  Wednesday 5:00 PM > > > and I want the array sorted by day name and then time. Is it possible to > > do this without resorting to a two stage process? Currently I am > > breaking the array out into arrays by day and sorting those by time and > > then reassembling... it just feels dirty :-) > > require 'date' > > def sort_datetime_array(ary) >   fmt = '%A %I:%M %p' >   ary.sort{ |a,b| >     DateTime.strptime(a, fmt) <=> DateTime.strptime(b, fmt) >   } > end Note that using sort is much slower than using sort_by (though perhaps slightly more memory-efficient). This is possibly only significant if you're sorting large amount of items, however. I mostly prefer sort_by because it is DRYer (and hence less typing :). require 'date' require 'benchmark' class Array; def rand; self[ Kernel.rand(length) ]; end; end DAYS = %w[ Monday Tuesday Wednesday Thursday Friday Saturday Sunday ] AMPM = %w[ AM PM ] FORMAT = '%A %I:%M %p' Benchmark.bmbm do |x| [10,100,1_000,10_000].each do |n| a = (0..n).map{ "#{DAYS.rand} #{rand(12)+1}:#{rand(60)} # {AMPM.rand}" } x.report( "sort #{n}") do a.sort{ |y,z| Date.strptime(y,FORMAT) <=> Date.strptime (z,FORMAT) } end x.report( "sort_by #{n}") do a.sort_by{ |y| Date.strptime(y,FORMAT) } end end end #=> Rehearsal ------------------------------------------------- #=> sort 10 0.020000 0.000000 0.020000 ( 0.020270) #=> sort_by 10 0.000000 0.000000 0.000000 ( 0.003464) #=> sort 100 0.200000 0.000000 0.200000 ( 0.204563) #=> sort_by 100 0.030000 0.000000 0.030000 ( 0.032382) #=> sort 1000 2.390000 0.040000 2.430000 ( 2.455060) #=> sort_by 1000 0.300000 0.010000 0.310000 ( 0.316943) #=> sort 10000 19.700000 0.280000 19.980000 ( 20.197492) #=> sort_by 10000 3.270000 0.060000 3.330000 ( 3.361712) #=> --------------------------------------- total: 26.300000sec #=> user system total real #=> sort 10 0.020000 0.000000 0.020000 ( 0.016442) #=> sort_by 10 0.000000 0.000000 0.000000 ( 0.003143) #=> sort 100 0.190000 0.000000 0.190000 ( 0.190505) #=> sort_by 100 0.030000 0.000000 0.030000 ( 0.026150) #=> sort 1000 2.300000 0.030000 2.330000 ( 2.351752) #=> sort_by 1000 0.290000 0.010000 0.300000 ( 0.298472) #=> sort 10000 19.020000 0.240000 19.260000 ( 19.437129) #=> sort_by 10000 3.310000 0.050000 3.360000 ( 3.389367)