>>>>> "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