arbitrary sorting...
Tkil
tkil at scrye.com
Thu Jul 18 18:33:27 CDT 2002
I wrote:
> if you know that @foo is a subset of @bar (that is, there are no
> elements of @foo that are not also in @bar), then you can do:
>
> | my %bar_score = do
> | {
> | my $i = 0;
> | map { $_ => ++i } reverse @bar;
^^^
> | };
> | my @foo_by_bar = sort { $bar_score{$a} <=> $bar_score{$b} } @foo
>
Sigh. The things I see when I'm awake. That should be ++$i, of
course.
One way to avoid the reverse is to start with a higher score, and
count down. (Or start with zero and go negative -- same difference.)
So, I'd probably really do it more like this:
| #!/usr/bin/perl -w
|
| use strict;
|
| my @bar = qw( porsche bmw audi buick ford chevy subaru jaguar
| horse cow dog cat pig
| sushi hamburger fish-n-chips burrito
| pear apple mango banana strawberry grapefruit orange );
|
| my @foo = qw( banana porsche subaru apple cat oddball buick cow mango );
|
| my @foo_by_bar = do
| {
| my $i = 0;
| my %s = map { $_ => ++$i } @bar;
| if (my @missing = grep !exists($s{$_}), @foo)
| {
| warn "not in bar: @missing\n";
| foreach (@missing) { $s{$_} = ++$i; }
| }
| sort { $s{$a} <=> $s{$b} } @foo;
| };
|
| print "foo: @foo\n",
| "by bar: @foo_by_bar\n";
If you are into micro-optimizations, it might be amusing to compare
the "map" scoring with something like:
| my %s;
| @s{@bar} = 0 .. $#bar;
Which might be a bit faster. I wouldn't make any wagers one way or
another, though. Heh. You'll have to adjust the backup scoring, too,
yielding:
| my @foo_by_bar = do
| {
| my %s;
| @s{@bar} = 0 .. $#bar;
| if (my @missing = grep !exists($s{$_}), @foo)
| {
| warn "not in bar: @missing\n";
| @s{@missing} = @bar .. @bar+ at missing-1;
| }
| sort { $s{$a} <=> $s{$b} } @foo;
| };
Anyway. Happy nugget polishing,
t.
TIMTOWTDI
More information about the Pdx-pm-list
mailing list