in reply to Custom Sort An AoA
This solution doesn't optimize for minimizing work inside the sort routine, but I think it does optimize for clarity and generality (it would be easy to substitute <=> for cmp, for example):
use Test::More tests => 1; my @unsorted = ( [ 'blah', 'asdf', 'foo', 'bar' ], ['two'], [ 'zzz', 'def', 'ghi' ], ['one'], [ 'mmm', 'def', 'ghi' ], [ 'qqq', 'xyz', 'aaa' ] ); my @wanted = ( ['one'], ['two'], [ 'qqq', 'xyz', 'aaa' ], [ 'mmm', 'def', 'ghi' ], [ 'zzz', 'def', 'ghi' ], [ 'blah', 'asdf', 'foo', 'bar' ] ); my @sorted = sort { @$a <=> @$b || do { my ( $left, $right ) = ( [@$a], [@$b] ); my $res = 0; $res = pop(@$left) cmp pop(@$right) while @$left && !$res; $res; }; } @unsorted; diag "@{$_}\n" for @sorted; is_deeply( \@sorted, \@wanted, 'Sorted array matches expectation.' );
Output.........
1..1 # one # two # qqq xyz aaa # mmm def ghi # zzz def ghi # blah asdf foo bar ok 1 - Sorted array matches expectation.
Update: Here's a version that doesn't waste time making copies of the elements for the purpose of pop:
use Test::More tests => 1; my @unsorted = ( [ 'blah', 'asdf', 'foo', 'bar' ], ['two'], [ 'zzz', 'def', 'ghi' ], ['one'], [ 'mmm', 'def', 'ghi' ], [ 'qqq', 'xyz', 'aaa' ] ); my @wanted = ( ['one'], ['two'], [ 'qqq', 'xyz', 'aaa' ], [ 'mmm', 'def', 'ghi' ], [ 'zzz', 'def', 'ghi' ], [ 'blah', 'asdf', 'foo', 'bar' ] ); my @sorted = sort { my $res; @$a <=> @$b || do { $res = $a->[$_] cmp $b->[$_] and return $res for reverse 0 .. $ +#{$a} }; } @unsorted; diag "@{$_}\n" for @sorted; is_deeply( \@sorted, \@wanted, 'Sorted array matches expectation.' );
Same output as above.
Dave
|
---|