Re: Sorting associative arrays in perl


Subject: Re: Sorting associative arrays in perl
From: Michael Fowler (michael@shoebox.net)
Date: Wed May 08 2002 - 10:30:21 AKDT


On Tue, May 07, 2002 at 04:15:19PM -0800, Leif Sawyer wrote:
[snip]
> 1) sort ascending, primarily, by the value (value is not unique)
> 2) sort ascending, secondarily, by the timestamp (timestamp is unique)
> 3) print the array
[snip]
> the output should resemble:
>
> 100, 200204311201
> 240, 200203192104
> 240, 200203192205
> 242, 200204301300
> 301, 200203302048
>
> I can't figure out how to write the sort subroutine to perform this
> type of sort.

Given the data structure:

    my %data = (
        200204311201 => 100,
        200203192104 => 240,
        200203192205 => 240,
        200204301300 => 242,
        200203302048 => 301,
    );

To sort it first by value, then by key you'd use something like:

    my @sorted = sort { $data{$a} <=> $data{$b} || $a <=> $b } keys(%data);

The way it works is if the values, $data{$a} and $data{$b}, are equal, the
comparison operator returns 0, and the second branch is tested.

You'd then print it with something like:

    while (my($timestamp, $value) = each(%data)) {
        print "$value, $timestamp\n";
    }

Or, more idiomatically:

    print map { "$data{$_}, $_\n" } @sorted;

This can all be combined:

    print
        map { "$data{$_}, $_\n" }
            sort { $data{$a} <=> $data{$b} || $a <=> $b }
                keys(%data);

But that may not be as readable.

Michael

--
Administrator                      www.shoebox.net
Programmer, System Administrator   www.gallanttech.com
--

--------- To unsubscribe, send email to <aklug-request@aklug.org> with 'unsubscribe' in the message body.



This archive was generated by hypermail 2a23 : Wed May 08 2002 - 10:30:32 AKDT