Sorting Array Of Dates

C

Chandu Chandu

Hi, Everyone I am a newbie to ruby....

just started with some examples

i have array

date = ['12/09/2007','06/06/2004','10/06/2005']

i wanted to sort dates in ascending order i.e
['06/06/2004','10/06/2005','12/09/2007']

tried using

p data.sort

could any one explain me whether there is built in class or need to
break tha date string

yyyy mm dd and compare ..

regards
chandu
 
P

Peña, Botp

RnJvbTogQ2hhbmR1IENoYW5kdSBbbWFpbHRvOmNoYW5kdV83NTBAeWFob28uY29tXSANCiMgaSB3
YW50ZWQgdG8gc29ydCBkYXRlcyBpbiBhc2NlbmRpbmcgb3JkZXIgaS5lDQojIFsnMDYvMDYvMjAw
NCcsJzEwLzA2LzIwMDUnLCcxMi8wOS8yMDA3J10NCiMgY291bGQgYW55IG9uZSBleHBsYWluIG1l
IHdoZXRoZXIgdGhlcmUgaXMgYnVpbHQgaW4gY2xhc3Mgb3IgbmVlZCB0bw0KIyBicmVhayB0aGEg
ZGF0ZSBzdHJpbmcNCiMgeXl5eSBtbSBkZCBhbmQgY29tcGFyZSAuLg0KDQp5b3UgaGF2ZSB0aGUg
aWRlYS4ganVzdCBjb250aW51ZSByZWFkaW5nIG1vcmUgb24gcnVieS4uDQoNCmVnLA0KDQo+IGRh
dGUgPSBbJzEyLzA5LzIwMDcnLCcwNi8wNi8yMDA0JywnMTAvMDYvMjAwNSddDQo9PiBbIjEyLzA5
LzIwMDciLCAiMDYvMDYvMjAwNCIsICIxMC8wNi8yMDA1Il0NCg0KPiBkYXRlLnNvcnRfYnl7fGR8
IG0sZCx5PWQuc3BsaXQoIi8iKTtbeSxtLGRdfQ0KPT4gWyIwNi8wNi8yMDA0IiwgIjEwLzA2LzIw
MDUiLCAiMTIvMDkvMjAwNyJdDQo=
 
C

Craig Demyanovich

[Note: parts of this message were removed to make it a legal post.]

Works for me in IRB:
date = ['12/09/2007','06/06/2004','10/06/2005'] => ["12/09/2007", "06/06/2004", "10/06/2005"]
p date.sort
["06/06/2004", "10/06/2005", "12/09/2007"]
=> nil

If it didn't work for you, could it be that you assigned to date but called
sort on data?

Regards,
Craig
 
R

Robert Klemme

2008/10/30 Chandu Chandu said:
Hi, Everyone I am a newbie to ruby....

just started with some examples

i have array

date = ['12/09/2007','06/06/2004','10/06/2005']

This is not an array of dates - it's an array of strings.
i wanted to sort dates in ascending order i.e
['06/06/2004','10/06/2005','12/09/2007']

tried using

p data.sort

could any one explain me whether there is built in class or need to
break tha date string

If these are dates you should use Date.

irb(main):005:0> date = ['12/09/2007','06/06/2004','10/06/2005']
=> ["12/09/2007", "06/06/2004", "10/06/2005"]
irb(main):006:0> real = date.map {|s| Date.parse s}
=> [#<Date: 4908887/2,0,2299161>, #<Date: 4906325/2,0,2299161>,
#<Date: 4907299/2,0,2299161>]
irb(main):007:0> puts real.sort
2004-06-06
2005-10-06
2007-12-09
=> nil

If for some serious reason you cannot use Date you should at least sort by Date:

irb(main):009:0> puts date.sort_by {|s| Date.parse s}
06/06/2004
10/06/2005
12/09/2007
=> nil
irb(main):010:0>

You need to require 'date' for this to work.

Kind regards

robert
 
B

Brian Candler

Chandu said:
i have array

date = ['12/09/2007','06/06/2004','10/06/2005']

i wanted to sort dates in ascending order i.e
['06/06/2004','10/06/2005','12/09/2007']

Apart from the other solutions mentioned, you could also just use ISO
dates instead:

date = ['2007-09-12','2004-06-06','2005-06-10']

http://en.wikipedia.org/wiki/ISO_8601#Calendar_dates

As well as sorting natively, this also has the advantage of being
absolutely clear which part is the month and which is the day. (In your
example, I can't tell whether you are using American middle-endian dates
or not)

Regards,

Brian.
 
J

Josef 'Jupp' Schugt

Hi, Everyone I am a newbie to ruby....

just started with some examples

i have array

date = ['12/09/2007','06/06/2004','10/06/2005']

i wanted to sort dates in ascending order i.e
['06/06/2004','10/06/2005','12/09/2007']

you forgot to mention if the date format is reasonable (dd/mm/yyyy) or not
(mm/dd/yyyy) - reasonable in the sense that the parts have an ascending or
descending significance and not an arbitrary one.

Anyway, here's a solution for both cases:

def datecmp(a, b, reasonable = true)
arra, arrb = a.split('/'), b.split('/')
cmp = (arra[2] <=> arrb[2])
return cmp if (cmp = (arra[2] <=> arrb[2])) != 0
if reasonable
(cmp = (arra[0] <=> arrb[0])) != 0 ? cmp : (arra[1] <=> arrb[1])
else
(cmp = (arra[1] <=> arrb[1])) != 0 ? cmp : (arra[0] <=> arrb[0])
end
end

date = ['12/01/2007', '11/02/2007', '11/11/2005']
puts "reasonable date format"
puts date.sort { |a, b| datecmp(a, b) }
puts "\nno reasonable date format"
puts date.sort { |a, b| datecmp(a, b, false) }

that results in

reasonable date format
11/11/2005
11/02/2007
12/01/2007

no reasonable date format
11/11/2005
12/01/2007
11/02/2007

but besides that the normal date format is yyyy-mm-dd.

I don't know about the situation in other countries but in Germany the
date format you SHOULD use (in an RFC sense, the DIN standard says so) is
that ISO standard form. Other formats are only tolerable but not
desireable. Which does not mean that many Germans use that format. You
hear me frequently protest against forms that still use antiquated date
formats :)

Josef 'Jupp' Schugt
 
B

Brian Candler

Josef said:
def datecmp(a, b, reasonable = true)
arra, arrb = a.split('/'), b.split('/')
cmp = (arra[2] <=> arrb[2])
return cmp if (cmp = (arra[2] <=> arrb[2])) != 0
if reasonable
(cmp = (arra[0] <=> arrb[0])) != 0 ? cmp : (arra[1] <=> arrb[1])
else
(cmp = (arra[1] <=> arrb[1])) != 0 ? cmp : (arra[0] <=> arrb[0])
end
end

date = ['12/01/2007', '11/02/2007', '11/11/2005']
puts "reasonable date format"
puts date.sort { |a, b| datecmp(a, b) }
puts "\nno reasonable date format"
puts date.sort { |a, b| datecmp(a, b, false) }

I think you got "reasonable" and "unreasonable" reversed (unless you are
American :)

Here is a shorter solution:

MapR = lambda { |x| x.split('/').values_at(2,1,0) }
MapU = lambda { |x| x.split('/').values_at(2,0,1) }

date = ['12/01/2007', '11/02/2007', '11/11/2005']
puts "reasonable date format"
puts date.sort_by(&MapR)
puts "\nno reasonable date format"
puts date.sort_by(&MapU)
 
W

William James

Josef said:
def datecmp(a, b, reasonable = true)
   arra, arrb = a.split('/'), b.split('/')
   cmp = (arra[2] <=> arrb[2])
   return cmp if (cmp = (arra[2] <=> arrb[2])) != 0
   if reasonable
     (cmp = (arra[0] <=> arrb[0])) != 0 ? cmp : (arra[1] <=> arrb[1])
   else
     (cmp = (arra[1] <=> arrb[1])) != 0 ? cmp : (arra[0] <=> arrb[0])
   end
end
date = ['12/01/2007', '11/02/2007', '11/11/2005']
puts "reasonable date format"
puts date.sort { |a, b| datecmp(a, b) }
puts "\nno reasonable date format"
puts date.sort { |a, b| datecmp(a, b, false) }

I think you got "reasonable" and "unreasonable" reversed (unless you are
American :)

Here is a shorter solution:

MapR = lambda { |x| x.split('/').values_at(2,1,0) }
MapU = lambda { |x| x.split('/').values_at(2,0,1) }

date = ['12/01/2007', '11/02/2007', '11/11/2005']
puts "reasonable date format"
puts date.sort_by(&MapR)
puts "\nno reasonable date format"
puts date.sort_by(&MapU)


MAP_R = proc{|x| x.split('/').reverse }
MAP_U = proc{|x| y=x.split('/'); [y.pop,y] }

dates = %w(12/01/2007 11/02/2007 11/11/2005)
puts "reasonable date format"
puts dates.sort_by(&MAP_R)
puts "unreasonable date format"
puts dates.sort_by(&MAP_U)
 
J

Josef 'Jupp' Schugt

I think you got "reasonable" and "unreasonable" reversed (unless you are
American :)

oops, you are right :) That much on quick hacks... ^^

Josef 'Jupp' Schugt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top