[plug] [Perl] sorign arrays based on scalar value

Matthew Robinson matt at zensunni.org
Fri Nov 15 16:36:47 WST 2002



Anthony J. Breeds-Taurima wrote:
> On Fri, 15 Nov 2002, Patrick Tehvand wrote:
> 
> 
>>'ello all,
>>I sent this to the SLPWA list by mistake...
>>
>>I've got another perl question,
>>I would like to sort in decending nemerical order based on $id
>>This is what I have.
>>
>>sub resort() {
>>   #Sort everthing out into numerical order
>>   my @final;
>>   my $inputfile=$_[0];
>>   open (THING,"<$inputfile");
>>   my @sortinput=<THING>;
>>   close THING;
>>      for $input(@sortinput) {
>>      chop ($input);
>>      ($id,$title,$words)=split(/\|/,$input);
>>
>>      @final = ____some sorting stuff___
>>
>>      open (RESORT,">$inputfile");
>>      for $line(@final) {
>>	print RESORT "$line";
>>      }
>>      close RESORT;
>>      return 0;
>>}
>>}
> 
> 
> use a Hash;
> sub resort($$) {
> 	my $inputfile = shift;               #Get function args.
> 	my $outputfile = shift;
> 
> 	#pre-decalre vars.
> 	my %allData;
> 
> 	#Open the input file
> 	open(IN, "<$inputfile") or die;
> 	while(<IN>) {
> 		# extract data into individual vars and store in a hash.
> 		chop;
> 		my ($id,$title,$words)=split(/\|/,$input);
> 
> 		$allData{$id}{title}=$title;		
> 		$allData{$id}{words}=$words;		
> 	}
> 	close(IN);
> 
> 	open(OUT,">$outputfile") or die;
> 
> 	#reverse sort by id [I'm assuming it's numeric] and output.
> 	foreach my $id (sort {$b <=> $a} keys %allData) {
> 		print join('|',$id,$allData{$id}{title},$allData{$id}{words}),
> 		      "\n";
> 	}
> 	close(OUT);
> 	retirn 0;
> }
> 
> It's not the only way to do it, and if your dat set is large then there are
> better ways but, this should demo the perl sort function.

TIMTOWTDI:  So here's another way to do it :) Also using the map() function:

sub resort($$) {
         my($inputfile, $outputfile) = @_;

         my %allData;

         open(IN, "<", $inputfile) or die;
         while(<IN>) {
                 my($id) = split(/\|/, $_, 1);
                 $allData{$id} = $_;
         }
         close(IN);

         open(OUT, ">", $outputfile) or die;
         print OUT map { $allData{$_} } sort {$b <=> $a} keys %allData;
         close(OUT);
}

Still not very good if you have a large data set as all the data is held 
in the hash in memory.


Matt


-- 
print map{s&^(.)&\U\1&&&$_}split$,=$",(`$^Xdoc$,-qj`=~m&"(.*)"&)[0].$/



More information about the plug mailing list