Front page | perl.beginners |
Postings from April 2003
Re: multiple sorts
Thread Previous
|
Thread Next
From:
Kevin Pfeiffer
Date:
April 28, 2003 01:32
Subject:
Re: multiple sorts
Message ID:
1241287.ApLlyalnbu@sputnik.tiros.net
In article <20030427114920.30143.qmail@onion.perl.org>, Rob Dixon wrote:
[...]
> I think you have an array of hashes, where each element
> of the array (@AoH?) is an anonymous hash reference. So
> I guess that should be
>
> @sortedAoH = sort {
> $a->{name} cmp $b->{name} ||
> $b->{age} <=> $b->{age}
> } @AoH
>
No, (perhaps I should have ;-)), an Arrayof arrays. And what you show is how
I started out.
>
> You want to sort data stringwise unless it is all numeric, when it should
> be sorted numerically?
Yes, and then I want to sort on three (or more?) columns of the table.
> I'm afraid you can't in general, because you need a sort routine that
> guarantees that data with equal sort keys stay in the same order. The
> Perl 'sort' function doesn't do this.
>
> The obvious solution is to provide a subroutine which will compare a
> pair of anonymous data numerically if both values are numbers, or
> stringwise if at least one is non-numeric. Like this
>
> sub compare {
> my ($a, $b) = @_;
> ($a =~ /\D/ or $b =~ /\D/) ?
> $a cmp $b :
> $a <=> $b
> }
>
> Then you can just rewrite you sort call as below.
[...]
>
> @data = sort {
> compare($a->{name}, $b->{name}) ||
> compare($a->{age}, $b->{age})
> } @data;
>
> print $_->{name}, ": ", $_->{age}, "\n"
> foreach @data;
[...]
Thanks, I see here how I can reduce the baggage - for some reason it never
occured to me to put this "is it numeric or not?" in a sub-routine - too
nervous about handling the sort properly I guess.
Thanks also to Janek for the module tip (ans also for the tip I saw
elsewhere on how to turn off specific warnings (i.e. "uninitialized
values").
-K
--
Kevin Pfeiffer
International University Bremen
Thread Previous
|
Thread Next