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 <u...@stemsystems.com> wrote:
> On 03/25/2014 11:41 AM, Jim Gibson wrote:
>>
>>
>> On Mar 25, 2014, at 7:56 AM, shawn wilson <ag4ve...@gmail.com> 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: beginners-unsubscr...@perl.org
> For additional commands, e-mail: beginners-h...@perl.org
> http://learn.perl.org/
>
>

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to