>>>>> "AS" == Aaron Sherman <[EMAIL PROTECTED]> writes:

  AS> On Thu, 2004-02-12 at 15:46, Uri Guttman wrote:
  >> 

  >> how do you select descending order? and how do you selecte that per
  >> key?

  >> you can't provide a binary operator without also providing the
  >> order. and what about different key types? the <=> and cmp
  >> operators are not enough information needed to do complex
  >> sorts. collating sequences are another issue. you need to have that
  >> info on a perl key basis.

  AS> I think my example addressed all of your concerns, and did it in Perl 5.
  AS> Once again, that was:

  AS>         sub sortpairs(&@) {
  AS>           my $comp = shift;
  AS>           my %pairs = @_;
  AS>           return map {$pairs{$_}} sort {$comp->()} keys %pairs;
  AS>         }
        
  AS>         @new1 = sortpairs {$a <=> $b} map {($_->computekey,$_)} @old1;
  AS>         @new2 = sortpairs {$a cmp $b} map {(lc($_),uc($_))} @old2;

  AS> So, in order, your questions were:

  AS>       * how do you select descending order?
  AS>         You reverse the $a and $b in the first parameter to sortpairs

i find that a poor solution. the $a cmp $b isn't needed in the ascending
case at all. a descending marker per key is better as it reflects the
results desired and not how it gets done. the reversing of $a and $b
requires the coder to understand sort comparison callbacks. it is
implementation exposed.

  AS>       *  and how do you selecte that per key?
  AS>         Ok, I was only addressing one key. But, it's not hard to
  AS>         generalize the idea, and certainly Perl 6 gives you the tools to
  AS>         do so easily.

i haven't seen any proposals other than mine (which is bad syntax but
good semantics) for this. and if you have multiple keys with each having
a $a <=> $b in there it will be very noisy.

  AS>       * you can't provide a binary operator without also providing the
  AS>         order.
  AS>   Correct

a single descending marker is simpler and better semantics.

  AS>       * and what about different key types? the <=> and cmp operators
  AS>         are not enough information needed to do complex sorts.
  AS>         That's fine, you can plug in a call to Alien::Headed::Babies
  AS>         inside the closure for all I care.

there are only a short list of key comparisons possible, int, string,
float and maybe unicode. i separate int from float since they do have
different internals in the GRT. it is one area where you do expose
stuff. otherwise you could just use number. 

  AS>       * collating sequences are another issue. you need to have that
  AS>         info on a perl key basis.
  AS>         Give me an example?

simple. pick almost any language char set other than US ascii. many have
special collating sequences. i am not anything close to a unicode expert
but i have seen this issue. in fact setting the LANG (or some other)
environment variable will affect many programs by changing the collating
order.


  AS>       * multiple keys with each having different comparisons and
  AS>         different sort orders.

  AS> Ok let's delve into it then:

  AS>         sub sortpairs(&@){
  AS>           my $comp = shift;
  AS>           my @elements = @_;
  AS>           return map {my $e=$elements[$_];$e->[$#{$e}]} sort {
  AS>              my @akeys = @{$elements[$a]}[0..$#{$elements[$a]}-1];

why the -1? that looks like:

        my @akeys = @{$elements[$a]} ;
        pop @akeys ;
        pop @akeys ;

  AS>              my @bkeys = @{$elements[$b]}[0..$#{$elements[$b]}-1];
  AS>              for(my $i=0;$i<@akeys;$i++) {
  AS>                my $dir = $comp->($akey[$i],$bkey[$i]);
  AS>                return $dir if $dir;
  AS>              }
  AS>              return 0;
  AS>           } 1..scalar(@elements);
  AS>         }

that is scary. do you realize that the sort block will be called for
each comparison?

  AS>         @new1 = sortpairs {$_[0] <=> $_[1]} map {[$_,$_]} @old1;

  AS>         @new2 = sortpairs {$_[0] <=> $_[1] || $_[4] cmp $_[3]} map
  AS>         {[getkeys($_),$_]} @old2;

where is getkeys defined? how do you know what indexes to use for each
comparison? what happened to $_[2]? your call to $comp is passed 2
arguments but the second example accesses 4 arguments.

  AS> The second example really illustrates the point that you can swap the
  AS> direction of key order and mechanism to compare them at your whim.

  AS> Now, you just need to call sortpairs with any array of arrays of keys
  AS> (with trailing value).

add a third key to that. quickly!

a more straightforward api (which is close to what i will do in
Sort::GRT) is (p5 code)

        my $sort = Sort::GRT->new(

                keys    => [
                        { descending => 1,
                          type => float,
                          extract => '$_->{amount},
                        },
                        { extract => 'substr( $_->{date}, 0, 4)' },
                ]
        ) ;

        my @sorted = $sort->do_it( @unsorted ) ;

        $sort->do_it_inplace( [EMAIL PROTECTED] ) ;

add a third key:

        my $sort = Sort::GRT->new(

                keys    => [
                        { descending => 1,
                          type => float,
                          extract => '$_->{amount}',
                        },
                        { extract => 'substr( $_->{date}, 0, 4)' },
                        { extract => '$_->{user}{last_name}' },
                ]
        ) ;

see? no issues with || or <=> or order or $_[4]. each key must have its
own type, order and extract code. the logical way to do that is a list
of hashes which is easy to describe and create a syntax for in p6. all
the other proposals i have seen here bypass this need for multikey
support.

uri

-- 
Uri Guttman  ------  [EMAIL PROTECTED]  -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs  ----------------------------  http://jobs.perl.org

Reply via email to