Forum: Ruby Sorting Array Of Dates

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
A416be304818269a504b0b3aa3869ebe?d=identicon&s=25 Chandu Chandu (chandu4ruby)
on 2008-10-30 02:28
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
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2008-10-30 02:39
(Received via mailing list)
From: Chandu Chandu [mailto:chandu_750@yahoo.com]
# i wanted to sort dates in ascending order i.e
# ['06/06/2004','10/06/2005','12/09/2007']
# could any one explain me whether there is built in class or need to
# break tha date string
# yyyy mm dd and compare ..

you have the idea. just continue reading more on ruby..

eg,

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

> date.sort_by{|d| m,d,y=d.split("/");[y,m,d]}
=> ["06/06/2004", "10/06/2005", "12/09/2007"]
B14575f0ca69f10938fdd67e7156e0e1?d=identicon&s=25 Craig Demyanovich (Guest)
on 2008-10-30 02:47
(Received via mailing list)
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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2008-10-30 09:29
(Received via mailing list)
2008/10/30 Chandu Chandu <chandu_750@yahoo.com>:
> 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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-10-30 10:15
Chandu Chandu wrote:
> 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.
3cb4fdcf13aad6a7dcae83876b0e784e?d=identicon&s=25 Josef 'Jupp' Schugt (Guest)
on 2008-10-30 13:48
(Received via mailing list)
On Thu, 30 Oct 2008 02:27:32 +0100, Chandu Chandu <chandu_750@yahoo.com>
wrote:

> 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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-10-30 16:01
Josef 'Jupp' Schugt wrote:
> 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)
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2008-10-30 18:05
(Received via mailing list)
On Oct 30, 10:00 am, Brian Candler <b.cand...@pobox.com> wrote:
> > end
> 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)
3cb4fdcf13aad6a7dcae83876b0e784e?d=identicon&s=25 Josef 'Jupp' Schugt (Guest)
on 2008-10-30 19:39
(Received via mailing list)
On Thu, 30 Oct 2008 16:00:56 +0100, Brian Candler <b.candler@pobox.com>
wrote:

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

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

Josef 'Jupp' Schugt
This topic is locked and can not be replied to.