|
Posted by Jim Gibson on June 11, 2008, 5:39 pm
Please log in for more thread options
> On Fri, 30 May 2008 13:11:22 UTC, Gunnar Hjalmarsson
>
> > dn.perl@gmail.com wrote:
> > > I want to sort a hash. The hash contains a list of cities and their
> > > temperature
> >
> > Well, I'd rather say it contains three hash references.
> >
> > This is one sensible way to sort that data structure:
> >
> > foreach my $state ( sort keys %hash ) {
> > print "State: $state\n";
> > foreach my $city ( sort { $a cmp $b } keys %{ $hash } ) {
> > print "$city = $hash\n";
> > }
> > print "\n";
> > }
>
>
> Sorry to jump in with another question but I have a very similar
> problem. I am processing a consolidated apache2 logfile. I have
> multiple virtual hosts. All I care about are the site, the page
> served, a counter and the date.
>
> So my hash looks like $urls Beyond that I have a counter
> and date thus:
> $urls[0]++; # count
> $urls[1] = $date;
>
> This works fine and I can list by site the page, count and date.
>
> foreach $site ( keys %urls)
> {
> foreach my $url (keys %})
> {
> print "$site $url $urls[0] $urls[1]\n";
> }
> }
>
> Putting a sort into the url loop gives me the results sorted by page
> as expected. What I cannot figure out is how to do it by count and by
> date.
>
> I have tried various ideas I found by google but they all tend to be
> similar to this
>
> sub by_count
> {
> $urls[0] <=> $urls[0] or $a cmp $b;
> }
>
> But this throws lots of "Use of uninitialized value....." errors on
> that line and in doing so gets the wrong pages attributed to a site. I
> have tried with yet another hash on the end with count & date keys
> instead of the array, but it does not help.
>
> I would be grateful for any pointers.
Are you trying to sort all of your records at once, regardless of site?
You can't do that with a simple sort. If you just want to sort the data
by site, here is an example:
#!/usr/local/bin/perl
use strict;
use warnings;
my %urls = (
site1 => {
url1_1 => [ 3, '2008-01-01' ],
url1_2 => [ 2, '2008-02-02' ],
url1_3 => [ 5, '2008-02-03' ],
url1_4 => [ 4, '2008-03-05' ],
},
site2 => {
url2_1 => [ 7, '2008-09-11' ],
url2_2 => [ 4, '2008-03-10' ],
url2_3 => [ 1, '2008-02-24' ],
url2_4 => [ 8, '2008-03-31' ],
}
);
print "Sorted by site, url:\n";
for my $site ( sort keys %urls ) {
for my $url ( sort keys %} ) {
my( $count, $date ) = @};
print "$site, $url, $count, $date\n";
}
}
print "Sorted by site, count:\n";
for my $site ( sort keys %urls ) {
for my $url (
sort { $urls->[0] <=> $urls->[0] }
keys %} )
{
my( $count, $date ) = @};
print "$site, $url, $count, $date\n";
}
}
If you want something else, please post a complete program showing what
you are trying to do. Thanks.
--
Jim Gibson
|