Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Re: Re: Re: Sorting by date

by Roger (Parson)
on Jan 06, 2004 at 01:19 UTC ( #318992=note: print w/replies, xml ) Need Help??

in reply to Re: Re: Sorting by date
in thread Sorting by date

use strict; use Data::Dumper; my %list = ( A => '1.13.04:Record:A', B => '1.12.04:Record:B', C => '3.13.04:Record:C', ); my @sorted_date = map { $_->[0] } sort { $b->[1] <=> $a->[1] } map { my @n = /^(\d+)\.(\d+)\.(\d+):/; my $d = sprintf "%02d%02d%02d", @n[2,0,1]; [join('.',@n), $d] } values %list; print Dumper(\@sorted_date);

OK, here's another variant of the sort that produces the HTML table as required...
use strict; use Data::Dumper; my %list = ( A => '1.13.04:Record:A', B => '1.12.04:Record:B', C => '3.13.04:Record:C', D => '3.13.02:Record:D', ); my @sorted_date = map { [ $_->[1], $_->[0], $_->[2] ] } sort { $b->[1] <=> $a->[1] } map { my @n = $list{$_} =~ /^(\d+)\.(\d+)\.(\d+):/; my $d = sprintf "%02d%02d%02d", @n[2,0,1]; [join('.',@n), $d, $_] } keys %list; my $month; foreach (@sorted_date) { my $m = substr($_->[0], 0, 4); # retrieve YYMM if ($month ne $m) { print "</table>\n" if $month; $month = $m; print "<table>\n"; } print "<tr><td>$_->[1]</td><td>HASH key: $_->[2]</td></tr>\n"; } print "</table>\n" if $#sorted_date >= 0;

And the output is:
<table> <tr><td>3.13.04</td><td>HASH key: C</td></tr> </table> <table> <tr><td>1.13.04</td><td>HASH key: A</td></tr> <tr><td>1.12.04</td><td>HASH key: B</td></tr> </table> <table> <tr><td>3.13.02</td><td>HASH key: D</td></tr> </table>

Replies are listed 'Best First'.
Re: Re: Re: Re: Sorting by date
by Anonymous Monk on Jan 06, 2004 at 01:53 UTC
    I thank you very much for your codes. I used the first part and it works AWESOME. Everything sorts so cleanly and perfectly. I can't get the table printing to work though, I get: Can't use string ("1.18.05") as an ARRAY ref while "strict refs" in use at ... So for some reason, something is acting up. But the first part of your code works wonders and I thank you very much for that!
      Can you show me what you have done? I suspect you are using the second part of the second example with the first part of the first example. The first example and the second example are different, the sort in the first example builds a sorted list of dates, while the sort in the second example builds a sorted list of array. You can not mix the two.

Re: Re: Re: Re: Sorting by date
by sulfericacid (Deacon) on Jan 06, 2004 at 10:40 UTC
    This is very interesting, though I can certainly admit I've always been afraid of looking into MAP and SORT (just the way it looks so complicated makes me cringe). One thing after looking over this a number of times that I still don't get is... You are taking an array and putting only the date inside, right? This seems to be what the original poster wanted anyway, but with mapping how are you supposed to draw back the rest of the %list's values?
    A => '1.13.04:Record:A', B => '1.12.04:Record:B', C => '3.13.04:Record:C', D => '3.13.02:Record:D',
    You are stripping apart the date into $_->[1], how would you find the Record or the letter afterwards? Let's say $_->[1] is 1.12.04 this time. How would you find Record and B and take that with it so you can use it later? Or is that data lost and only the date can be retrieved after you've mapped?

    At this level of confusion, unless this question makes sense and can be answered without digging the hole any deeper, even attempting a project which requires mapping or sorting like this is just not likely to happen in the near future.

    Thanks for your time, everyone.

    "Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

      That's why the sorted record I built has three parameters, normalized date, original date string, and a hash key. You retrieve the rest of the data with the hash key, which is $_->[2]. And also remember that how to optimize the storage/retrieval depends on what sort of output is required.

      The code is actually quite simple, really. The sorting part is based on the Schwartzian Transform, invented by merlyn.

      The following is the explanation of the sort, hope you might find it useful. ;-)
      my @sorted_date = map { [ $_->[1], $_->[0], $_->[2] ] } sort { $b->[1] <=> $a->[1] } map { my @n = $list{$_} =~ /^(\d+)\.(\d+)\.(\d+):/; my $d = sprintf "%02d%02d%02d", @n[2,0,1]; [join('.',@n), $d, $_] } keys %list; step 1: build a list of hash keys: keys %list; step 2: build a new array by: for each element of the list built in step 1, capture the MM, DD and YY values into @n with the @ary = $str =~ /pattern/ idiom, normalize the date into YYMMDD form, store the original date, normalized date and hash key in anonymous array step 3: do the sort on normalized dates step 4: just reshuffle the fields in sorted data.
Re: Re: Re: Re: Sorting by date
by Anonymous Monk on Jan 07, 2004 at 05:48 UTC
    I am sorry to bug you again. I've fiddled with this code a great deal but then I realized I had to change the script just a little bit. Now I'm lost as to how to make the little change I need to get it working again.

    The date we separated earlier was month, day, year. I now have to make it seperate by day, month, year (Britian's way of doing dates). I tried changing the line @n[2,0,1]; to @n[1,0,2]; but no changes occured. Is there something else I have to change to make it separate the string into day, month, year instead of month, day, year?

    Again, sorry for bothering you. Hopefully there is a quick fix for this.

      @n[2,1,0] # shuffle from DD MM YY ==> YY MM DD or reverse @n # reverse the order

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://318992]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2018-02-19 20:12 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (266 votes). Check out past polls.