On Thu, 2004-02-12 at 18:50, Uri Guttman wrote: > 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.
And comparing in a particular language (as Dan pointed out in his Parrot talk); comparing sets (e.g. numeric comparison, but odds and evens are separate); ordering by string length; ordering by string-to-numeric value with esoteric exceptions (software versions); etc. Comparison is essentially always numeric, but only if you reduce your inputs to numbers, and that's often not terribly efficent (e.g. you can reduce any ascii string to: chr(substr($s,0,1))+chr(substr($s,1,1))*128+... and then comparing. The only limitation is that you'll have to use Math::BigInt to do the comparison. > 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. Ok, yes. This was Dan's example, and is EXACTLY why I think you want to use map once for key extraction and then sort's expression for comparison. > that is scary. do you realize that the sort block will be called for > each comparison? Yes.... why would it not be? How do you compare, say, IPv6 addresses if not by performing a logically-ored comparison between each octet? I certainly don't want to instantiate a Math::BigInt just to compare two 128-bit values. > AS> @new1 = sortpairs {$_[0] <=> $_[1]} map {[$_,$_]} @old1; > > AS> @new2 = sortpairs {$_[0] <=> $_[1] || $_[4] cmp $_[3]} map > AS> {[getkeys($_),$_]} @old2; > > where is getkeys defined? It was an example. It's whatever you like. In some cases, that might just be: sub getkeys { my $object = shift; return @{$object->keys}; } or perhaps: sub getkeys { my $string = shift; return(length($string),$string); # Order by length and then ascii order } It was just an example. sortpairs was the interesting part. > 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. You missed a layer of extraction there. $comp is passed each parameter PAIR. So if your input is [1,2,3,4,"moo"], then you are comparing the keys 1, 2, 3 and 4 and your value is "moo". > 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! ok, easy: @new2 = sortpairs {$_[0] <=> $_[1] || $_[4] cmp $_[3] || ACME::Compare::Thingulas->compare($_[5],$_[6])} map {[getkeys($_),$_]} @old2; Please notice that the ONLY change is in the way I call it, not in sortpairs. sortpairs still works just fine. > 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)' }, > ] > ) ; The value of extract should be a subref, not a string (thus having closure status, and therefore access to context). I think you and I are in violent agreement. I just look at this as a problem that doesn't need solving because Schwartzian Transforms do all the work for me. You look at it as something needing encapsulation. That's cool, but sematically, we're doing the same work. -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback