in reply to Complex hash sorting
Keep in mind that as others have mentioned, turning your hash values into array-refs is probably a better solution, but I'm going to just work with the assumption that you really do want to keep that '||' delimited list as the value to each hash element.
First, the straight sort:
my $criteria = 3; my @sorted = sort { (split /\|\|/, $hash{$a} )[$criteria] cmp (split /\|\|/, $hash{$b} )[$criteria] } keys %hash +;
The method listed above indexes into the split list, using the specified sub-element as the sort criteria.
This next method will allow any arbitrary number of sort criteria, in the order you choose.
my @criteria = (0, 2); my @sorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [ $_, join( "", ( split /\|\|/, $hash{$_} )[@sorted +] ] } keys %hash;
This second method uses a Schwartzian Transform in conjunction with join to create a single sort criteria comprised of the slice created by taking (possibly multiple) indexes into the split results.
The shortcoming here is that we're doing all string comparison, which sort of wreks havok on strings that have numeric components. But the advantage here is that you can actually specify multiple sort criteria in one search easily.
There are an infinate number of other ways to do this. Here are some thoughts:
You might use eval and build your sort routine dymanically (once) so that it can be of arbitrary complexity, chained together with the logical short-circuit 'or' operator. This will allow the user to specify that he/she needs to sort by the 0th, 2nd, and 1st criteria today, but the 1st and 4th later. Also, by building it up dynamically, you can at runtime decide whether to do a 'cmp' or an '<=>' comparison. I give a simple example of this technique in Fun with complex sorting on arbitrary criteria list.. My example implementation has a few shortcomings too, but most could be overcome without too much extra work.
Dave
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Complex hash sorting
by Anonymous Monk on Feb 01, 2004 at 09:55 UTC | |
by flyingmoose (Priest) on Feb 02, 2004 at 19:16 UTC |