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/