Thanks guys:
# Preceed sort with possible presorted values from an array.
sub _sortpre
{
my ($self, $data, $prevals) = @_;
my $i = 1;
my $pre = (ref($prevals) eq 'ARRAY' and scalar(@$prevals) ?
{map {$_ => $i++} @$prevals} : {}
);
return
sort {
return $pre->{$a} <=> $pre->{$b}
if $pre->{$a} && $pre->{$b};
return -1 if $pre->{$a};
return +1 if $pre->{$b};
return $a cmp $b;
} @$data;
}
On Tue, Mar 25, 2014 at 11:53 AM, Uri Guttman <[email protected]> wrote:
> On 03/25/2014 11:41 AM, Jim Gibson wrote:
>>
>>
>> On Mar 25, 2014, at 7:56 AM, shawn wilson <[email protected]> wrote:
>>
>>> Thanks (y'all). Though, I like this one best I think.
>>>
>>> BTW, Jim's isn't exactly correct:
>>> my @keys = qw( foo bar second baz first third );
>>>
>>> my %primary = ( second => 1, first => 1, third => 1);
>>>
>>> And then the output becomes:
>>> Sorted: first, second, third, bar, baz, foo
>>>
>>> Which isn't correct.
>>
>>
>> I humbly beg to differ. Your specification was to sort ‘first’, ‘second’,
>> or ‘third’ before other keys, and the solution I provided does exactly that,
>> sorting ‘first’, ‘second’, and ‘third’ in alphabetic order before the other
>> keys.
>>
>> The values assigned to the %primary hash are irrelevant and are not used
>> in any comparison. The existence of the key,value pair in the hash is used
>> to specify which keys are the primary ones.
>>
>> If you want to specify what order the primary keys should occur, rather
>> than simple alphabetic order, then you will have to modify the program:
>>
>> #!/usr/bin/perl
>> use strict;
>> use warnings;
>>
>> my @keys = qw/foo bar baz first second third/;
>>
>> my %primary = ( first => 3, second => 2, third => 1); # different values
>> for each key giving sort order (1, 2, 3, etc.)
>>
>> my @sorted;
>> @sorted = sort {
>> if( $primary{$a} && $primary{$b} ) {
>> return $primary{$a} <=> $primary{$b};
>> }elsif( $primary{$a} ) {
>> return -1;
>> }elsif( $primary{$b} ) {
>> return +1;
>> }else{
>> return $a cmp $b;
>> } } @keys;
>
>
>
> as a coding style thing, when you have basic flow control in if/else blocks,
> you can use statement modifiers and drop the blocks. this will shorten the
> code, make it a bit faster (block entry is slow), reduce indents, and save
> on braces and pixels (which are VERY costly :).
>
>
> return $primary{$a} <=> $primary{$b}
> if $primary{$a} && $primary{$b} ;
> return -1 if $primary{$a} ;
> return +1 if $primary{$b} ;
> return $a cmp $b;
>
> also if the list is very large, it would be optimal to do this key ordering
> conversion one time for each element instead of once per comparison. see
> Sort::Maker for how this can be done efficiently.
> the simplest way would be to make a hash of all possible keys with their
> ordering as the values. then a basic hash lookup is done for each key in the
> comparision or the precomputed keys.
>
>
> uri
>
>
> --
> Uri Guttman - The Perl Hunter
> The Best Perl Jobs, The Best Perl Hackers
> http://PerlHunter.com
>
>
> --
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> http://learn.perl.org/
>
>
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/