[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] Sorting lines in a file



On Wed, May 19, 1999 at 01:52:18PM -0500, JDE wrote:
> ##my umpteenth, and most enterprising attempt
> ##  - using what I thought was a sort function call:
> ####
> sub extractElement	{
> 	$oneLine = shift(@_);
> 	@oneLineAsList = split(/\t/,$oneLine);
> 	$chosenElement = $oneLineAsList[2];
> 	return $chosenElement;
> }
> @sortedOrder = sort { &extractElement($a) cmp &extractElement($b) } @allLines;
> ####
> 

This code works as expected for me:

#!/usr/local/bin/perl

sub extractElement      {
        $oneLine = shift(@_);
        @oneLineAsList = split(/\t/,$oneLine);
        $chosenElement = $oneLineAsList[2];
        return $chosenElement;
}

@allLines = split /^/, <<EOLINES;
first\tabc\tsort_2\tabc
second\tabc\tsort_1\tabc
EOLINES
    ;

print "unsorted:\n", @allLines;

@sortedOrder = sort { &extractElement($a) cmp &extractElement($b) }
               @allLines;

print "sorted:\n", @sortedOrder;

__END__
unsorted:
first   abc     sort_2  abc
second  abc     sort_1  abc
sorted:
second  abc     sort_1  abc
first   abc     sort_2  abc


I have no idea why it doesn't work for you.  Could you provide a short but
complete script which shows the problem you are having?


Note that Perl subroutine calls are expensive, so it would be better to
perform all the extraction inside the actual sort sub:

sort { (split /\t/, $a)[2] cmp (split /\t/, $b)[2] } @allLines;


But even better would be to extract out the necessary fields before the
sort, so you don't have to repeat them for each comprison.

@sortedOrder = map {$_->[1]}
               sort {$a->[0] cmp $b->[0]}
               map {[(split /\t/, $_)[2], $_]}
               @allLines;

That's called a Schwartzian Transform.  The inner map creates a list of
anonymous arrays, the sort sorts on the first element in the anonymous
arrays, and the outer map extracts the second element, which is the
original line, from each anonymous array.


Ronald

===== Want to unsubscribe from this list?
===== Send mail with body "unsubscribe" to macperl-request@macperl.org