[Note: parts of this message were removed to make it a legal post.]
Morning Tim,
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)