PsySkeletor has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks! I facing a problem what it should be easy to fix it but i don't know how. I have a script which opens a lot of log files and pull the data to different hashes. For the sake of organization, i translate the dates to epoc and organize in my hash the info using the epoc time as the second hash, to prevent duplicates and to sort the hash results to present them in chronologic order. Well, the problem its sort isn't sorting epoc numbers :(
foreach $cat ( keys %data ) { foreach $date ( keys %{ $data{$cat} }) { print "<tr>"; foreach $data_type (sort { $a cmp $b } keys %{ $data{$cat}{$da +te} } ) { print "<td align='left'>$data{$cat}{$date}{$data_type}</td +>"; #print "<br>"; } print "</tr>"; } }
$cat = category, i have 4, that runs. $date = its the date en epoc, this doesn't run $date_type = the type of data we are going to print, this works. The results of the sort that is not shorting are:
EPOC IP 1405799856 79.223.46.211 1405879428 79.200.95.44 1405702121 87.149.76.154 1407101135 188.138.41.140 1406108233 82.139.192.95 1407162997 87.149.66.39 1405810508 80.187.110.214 1405791762 84.159.197.17 1405870826 2.246.106.240 1406040423 87.154.119.73 1405810525 85.22.101.198 1405620262 87.149.72.59 1405603261 178.12.215.30 1405806556 80.187.102.26
As you can see, there is not sorting. :(

Replies are listed 'Best First'.
Re: sort on hash / hash / hash doesn't work
by AppleFritter (Vicar) on Jul 12, 2014 at 17:33 UTC

    I'm not entirely sure what sort order you're expecting there. You're not sorting the timestamps; you're also not sorting the data, merely the keys for each piece of data, so that the keys will always appear in lexicographical order. For instance, if for each chunk of data and each timestamp, your hash contained values for e.g. IP, REFERER and URL, you'd always get them in that order.

    I take it you'd like to sort by timestamp? Simply add a sort in foreach $date ( keys %{ $data{$cat} }) {, like so (I've also taken the liberty of adding my declarations so the script will compile under use strict, and removing the HTML bits so that the output's easier to read):

    #!/usr/bin/perl use feature qw/say/; use warnings; use strict; my %data = ( 1 => { "1405799856" => { IP => "79.223.46.211" }, "1405879428" => { IP => "79.200.95.44" }, "1405702121" => { IP => "87.149.76.154" }, "1407101135" => { IP => "188.138.41.140" }, "1406108233" => { IP => "82.139.192.95" }, "1407162997" => { IP => "87.149.66.39" }, "1405810508" => { IP => "80.187.110.214" }, "1405791762" => { IP => "84.159.197.17" }, "1405870826" => { IP => "2.246.106.240" }, "1406040423" => { IP => "87.154.119.73" }, "1405810525" => { IP => "85.22.101.198" }, "1405620262" => { IP => "87.149.72.59" }, "1405603261" => { IP => "178.12.215.30" }, "1405806556" => { IP => "80.187.102.26" }, } ); foreach my $cat ( keys %data ) { foreach my $date ( sort keys %{ $data{$cat} }) { foreach my $data_type (sort { $a cmp $b } keys %{ $data{$cat}{ +$date} }) { say "$date\t$data{$cat}{$date}{$data_type}"; } } }

    EDIT: added a few characters that didn't copy'n'paste, thanks redbull2012.

      yes, but better sort numerically than lexicographically:
      foreach my $date ( sort { $a <=> $b } keys %{ $data{$cat} }) { # ^^^^^^^^^^^^^

      You missed "){" at the third "foreach"

      Regards

Re: sort on hash / hash / hash doesn't work
by poj (Abbot) on Jul 12, 2014 at 17:38 UTC
    foreach $date ( sort keys %{ $data{$cat} }) { ^^^^ add
    poj
Re: sort on hash / hash / hash doesn't work
by redbull2012 (Sexton) on Jul 13, 2014 at 06:18 UTC

    Hello,

    Perhaps the problem is in your %data, you should use the Data::Dumper module to print out the structure of %data to make sure that you stored the right thing.

    use Data::Dumper; print Dumper(\%data);

    Regards,