On Tuesday, July 24, 2001, at 10:36 , Clinton A . Pierce wrote:
> While tinkering with a problem at work (listed below) I was considering
> why perl couldn't have an in-place sort function. #perl noted
> that this
> could be done in XS, certainly. I thought maybe this was worthy of
> hacking into Perl itself as a use for void (or scalar) context sort().
>
> But then a thought occurred. Within a sort block, $a and $b are just
> aliases to the list being processed. Would it be possible to
> do something
> like this:
>
> @dummy=sort {
> $r=$a cmp $b;
> if ($r < 0) {
> ($a,$b)=($b,$a);
> $r=1;
> }
> $r;
> } @list;
> # Is @list sorted? Not quite...
>
> Except this doesn't work. Oh, $a and $b get modified and
> they're swapped
> at appropriate times, but the resulting mess in @list can
> hardly be called
> proper ordering.
I think the sense on your if is reversed. I have little proof,
just empirical evidence.
> I guess the questions are: 1. why doesn't this work? and 2. can it be
> made to work?
2. Yes, sort of.
#!/usr/bin/perl -w
use strict;
my @list = (1, 4, 2, 8, 5, 7, 3, 6, 0, 9);
my @sorted = sort { $a <=> $b } @list;
for (1..@list) {
my @dummy = sort {
($a,$b) = ($b,$a) if (($a <=> $b) > 0);
0;
} @list;
}
local $, = ', ';
print "Original: @list\n";
print "Sorted: @sorted\n";
__END__
It's painfully inefficient, thanks to the for loop, and I don't
think it buys you anything, since @dummy takes up memory anyway.
But it *does* sort in place, which is what you asked for. :-)
> Further, what could a read/write $a and $b be used for within a sort
> block that might be considered useful?
Hmm. Shuffling the contents of a list?
#!/usr/bin/perl -w
use strict;
my @list = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
local $, = ', ';
print "Original: @list\n";
for (1..6) {
my @dummy = sort {
($a,$b) = ($b,$a) if ((rand(2) - 1) < 0);
0;
} @list;
}
print "Shuffled: @list\n";
__END__
For varying degrees of "useful", of course.
--
Craig S. Cottingham
[EMAIL PROTECTED]
PGP key available from:
<http://pgp.ai.mit.edu:11371/pks/lookup?op=get&search=0xA2FFBE41>
ID=0xA2FFBE41, fingerprint=6AA8 2E28 2404 8A95 B8FC 7EFC 136F
0CEF A2FF BE41