in reply to Optimizing a sort function (wrap-around alpha)

I have a module on CPAN that makes it really easy:
use Sort::Key; @sorted = keysort { ($_ ge $top ? 'a' : 'b').$_ } @unsort;

Replies are listed 'Best First'.
Re: use Sort::Key
by dragonchild (Archbishop) on Apr 15, 2005 at 15:24 UTC
    What should happen in this case?
    my @data; foreach ( 1 .. 100 ) { push @data, [ map { rand(200) - 100 } 1 .. 100 ]; } my $pivot = 0; my @sorted = keysort { my $v = $_; my @v = keysort { $_ > $pivot ? 1 : -1 } @{$v}; $v[50] } @data;
      well, what are you trying to do?

      The inner keysort on your code is equivalent to:

      @v=((grep { $_ <= $pivot } @$v), (grep { $_ > $pivot } @$v));
      is that what you intended?

      I suppose that what you really want is to mimic the sort on the original post but numerically: sort first the elements > $pivot and then the rest.

      Then, for your specific data, integers between -100 and 100, this works:

      my @v=nkeysort { $_<$pivot ? $_ + 200 : $_ } @$v;
      but if you know nothing about the numbers in $@v, then figuring a convenient sorting key can be quite difficult, it's easier to just use a grep/sort combination:
      my @v=((sort {$a<=>$b} (grep { $_ >= $pivot } @$v)), (sort {$a<=>$b} (grep { $_ < $pivot } @$v)));
      that inserted on the outer sort becomes:
      my @sorted = nkeysort { ( ( sort {$a<=>$b} (grep { $_ >= $pivot } @$_) ), ( sort {$a<=>$b} (grep { $_ < $pivot } @$_) ) )[50] } @data;
      BTW, note that for numeric keys you have to use nkeysort.
        I'm trying to see if you know what should happen if you have a keysort within a keysort. You built your module based on the &@ prototype. You don't have a test for a keysort in a keysort, to make sure you don't trip anything, especially on earlier implementations of prototypes (like 5.6.0). You should have a test for that. :-)