473,545 Members | 1,779 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Sorting data with perl - Part One

KevinADC
4,059 Recognized Expert Specialist
Introduction

This discussion of the sort function is targeted at beginners to perl coding. More experienced perl coders will find nothing new or useful. Sorting lists or arrays is a very common requirement of programs. If you don't know the difference between a list and array don't worry about it. A list is just an array without a name. They both can hold the same type of data: scalars or strings. I will use the terms "list" and "array" to mean the same thing.

The sort() Function

The sort() function sorts a copy of the original list and returns a new list. This means you can't use the sort() function in a void context like you can with some of perls other built-in functions:

Expand|Select|Wrap|Line Numbers
  1. sort(@array); # bad - void context
You have to assign the results to an array using the assignment operator "=":

Expand|Select|Wrap|Line Numbers
  1. @sorted = sort(@arrray);
But you can use the same name as the original array to sort the original array:

Expand|Select|Wrap|Line Numbers
  1. @array = sort(@arrray);
Keep in mind that the original unsorted values of @array are gone when you do that.

Perl's built-in function for sorting is generally not much use with real-world data. The default sort is by standard string comparison. To the uninitiated perl coder this can be quite confusing. Lets look at an example.

Expand|Select|Wrap|Line Numbers
  1. @array = qw(@foo 1 32 11 4 2 44 22 !bar Mary mary Adam ant xxx XXX);
  2. @sorted = sort (@array);
  3. print "$_\n" for @sorted;
  4.  
The sorted output would be:

Expand|Select|Wrap|Line Numbers
  1. !bar
  2. 1
  3. 11
  4. 2
  5. 22
  6. 32
  7. 4
  8. 44
  9. @foo
  10. Adam
  11. Mary
  12. XXX
  13. ant
  14. mary
  15. xxx
  16.  
The output is sorted in ascending ASCII value, not very useful for most practical applications. But if you were sorting normalized data, all lower-case alpha strings for example, the default sort will work without you having to do anything else.

To sort data in descending order prefix the sort function with the reverse function:

Expand|Select|Wrap|Line Numbers
  1. @sorted = reverse sort (@array);
Another method is to use a code block and perls "cmp" string comparison operator:

Expand|Select|Wrap|Line Numbers
  1. @sorted = sort {$b cmp $a} @array; # descending order same as reverse sort above
  2. @sorted = sort {$a cmp $b} @array; # ascending order same as the default sort 
  3.  
I did not arbitrarily decide to use $a and $b in the above example. $a and $b are special scalar variables that perl uses to sort data. You should avoid using them in your perl programs for anything else and they should not be declared with "my" when using the "strict" pragma.

Part Two will discuss more advanced ways to sort data using perl.

This article is protected under the Creative Commons License .
Dec 23 '07 #1
5 6671
KevinADC
4,059 Recognized Expert Specialist
As of perl 5.10 this comment is no longer true:

The sort() function sorts a copy of the original list and returns a new list. This means you can't use the sort() function in a void context like you can with some of perls other built-in functions:
Perl no longer sorts a copy of an array if you sort the original array ( in-place sorting ):

Expand|Select|Wrap|Line Numbers
  1. @array = sort @array;
But you still can't use the sort() function in a void context. There have been other changes to the sort() function in perl 5.10 which can be read on the perldoc.perl.or g website on the History/Changes page.
Jan 17 '08 #2
Kelicula
176 Recognized Expert New Member
Also for numbers..


Expand|Select|Wrap|Line Numbers
  1.  
  2. @array = qw(7 8 59 58 4  5 6 2 59);
  3.  
  4. @array2 = sort {$a <=> $b } @array;
  5.  
  6.  
Only the comparison operator is changed.

cmp for strings
<=> for numerical
Feb 24 '08 #3
rohitbasu77
89 New Member
Also for numbers..


Expand|Select|Wrap|Line Numbers
  1.  
  2. @array = qw(7 8 59 58 4  5 6 2 59);
  3.  
  4. @array2 = sort {$a <=> $b } @array;
  5.  
  6.  
Only the comparison operator is changed.

cmp for strings
<=> for numerical
I am little confused what it print for $a and $b, how the comparision is really happening. can you explain.....

#!/usr/bin/perl

@array = qw(7 8 59 58 4 5 6 2 59);

@array2 = sort {$a <=> $b; print "$a and $b.... comp.. \n"; } @array;


print "$_\n" for @array2;
Feb 25 '08 #4
Kelicula
176 Recognized Expert New Member
I am little confused what it print for $a and $b, how the comparision is really happening. can you explain.....

#!/usr/bin/perl

@array = qw(7 8 59 58 4 5 6 2 59);

@array2 = sort {$a <=> $b; print "$a and $b.... comp.. \n"; } @array;


print "$_\n" for @array2;
$a and $b are "internal" global perl variables. As mentioned earlier in Kevin's article.
I did not chose those names. When testing for comparison the "block" or function will return one of three values: -1, 0, 1.

example:
Expand|Select|Wrap|Line Numbers
  1.  
  2. $test = 31;
  3. $test2 = 32;
  4.  
  5. print $test <=> $test2;
  6.  
The output is: -1.

Here is how I think of it: $test2 must "go back" to reach $test value.

If $test were larger than $test2:
Expand|Select|Wrap|Line Numbers
  1.  
  2. $test = 40;
  3. $test2 = 32;
  4.  
  5. print $test <=> $test2;
  6.  
The output is: 1.

Then $test2 must "go forward" to reach $test value. "1"

If they are the same:
Expand|Select|Wrap|Line Numbers
  1.  
  2. $test = 31;
  3. $test2 = 31;
  4.  
  5. print $test <=> $test2;
  6.  
The output is: 0.

$test2 doesn't need to go "anywhere" to reach $test value.

{} is known in perl as an anonymous "block".
When using sort the block must return 1, 0, or -1.

You can actually write your own subroutine in that place as long as it returns either 1, 0, or -1. Example:
Expand|Select|Wrap|Line Numbers
  1. sort sortit @array;
  2.  
  3. sub sortit { 
  4. $a <=> $b
  5. }
  6.  
This can be very useful for sorting multilevel arrays and/or hashes.
Here is a sub that will sort a hash, based on it's values, and if two keys have the same value it sorts according to the key.

Let's say you own a department store, and want to keep track of the various departments sales for each month. You would like the departments that earn the most money listed first, and departments that sale the same amount to be alphabetically sorted by name.

Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/perl -Tw
  2.  
  3. use strict;
  4.  
  5. my %sale = ( 'Sound'=> 45,
  6.              'Lighting'=> 25,
  7.              'Electronics'=> 89,
  8.              'Extra'=> 25,
  9.              'Clothing'=> 45,
  10.              'Home Goods'=> 67);
  11.  
  12. for my $dept ( sort sort_num_name keys %sale){
  13. print "$dept sold: \$$sale{$dept}\n";
  14. }
  15.  
  16. sub sort_num_name {
  17. $sale{$b} <=> $sale{$a} ||
  18. $a cmp $b;
  19. }
  20.  
This will output:
Expand|Select|Wrap|Line Numbers
  1. Electronics sold: $89
  2. Home Goods sold: $67
  3. Clothing sold: $45
  4. Sound sold: $45
  5. Extra sold: $25
  6. Lighting sold: $25
  7.  
This is because 0 is false to perl, so when two values are identical they return 0, and then the "||" or statement is executed.

You should never alter the values of $a or $b. You also cannot pass $a and $b into the sub via "$_". As well as you cannot use "next", "last", or recursive subroutines. $a and $b will be set by perl within the lexical scope of the sort function call. (You can use this same sub later to sort another Hash)


Read more here: Perldoc sort
Feb 26 '08 #5
KevinADC
4,059 Recognized Expert Specialist
Also for numbers..


Expand|Select|Wrap|Line Numbers
  1.  
  2. @array = qw(7 8 59 58 4  5 6 2 59);
  3.  
  4. @array2 = sort {$a <=> $b } @array;
  5.  
  6.  
Only the comparison operator is changed.

cmp for strings
<=> for numerical
Good comment. Thanks for adding it to the article.
Feb 27 '08 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

2
2197
by: Xah Lee | last post by:
Today we'll write a program that can sort a matrix in all possible ways. Here's the Perl documentation. I'll post a Perl and Python version in 2 days. ----------- sort_matrix( $matrix, , , ...]) sorts a matrix by $n1 th column then $n2 th...and so on.
7
3242
by: Federico G. Babelis | last post by:
Hi All: I have this line of code, but the syntax check in VB.NET 2003 and also in VB.NET 2005 Beta 2 shows as unknown: Dim local4 As Byte Fixed(local4 = AddressOf dest(offset)) CType(local4, Short) = CType(src, Short)
20
4030
by: Xah Lee | last post by:
Sort a List Xah Lee, 200510 In this page, we show how to sort a list in Python & Perl and also discuss some math of sort. To sort a list in Python, use the “sort” method. For example: li=;
19
2889
by: George Sakkis | last post by:
It would be useful if list.sort() accepted two more optional parameters, start and stop, so that you can sort a slice in place. In other words, x = range(1000000) x.sort(start=3, stop=-1) would be equivalent to x = sorted(x)
5
1853
by: cnsabar | last post by:
Hi., I am having the index pg no. data in file .. i need to sort the data ., Can any one help regarding this using PERL .. Its very urgent ... Source file <ce:intra-ref id="10011#f0070"/>310f, <ce:intra-ref id="10011#s0120"/>308--309 <ce:intra-ref id="10011#f0130"/>313f, <ce:intra-ref id="10011#p0310"/>313 <ce:intra-ref...
1
7170
KevinADC
by: KevinADC | last post by:
Introduction In part one we discussed the default sort function. In part two we will discuss more advanced techniques you can use to sort data. Some of the techniques might introduce unfamiliar methods or syntax to a less experienced perl coder. I will post links to online resources you can read if necessary. Experienced perl coders might find...
3
7308
KevinADC
by: KevinADC | last post by:
If you are entirely unfamiliar with using Perl to sort data, read the "Sorting Data with Perl - Part One and Two" articles before reading this article. Beginning Perl coders may find this article uses unfamiliar terms and syntax. Intermediate and advanced Perl coders should find this article useful. The object of the article is to inform the...
7
1908
by: Steve Bergman | last post by:
I'm involved in a discussion thread in which it has been stated that: """ Anything written in a language that is 20x slower (Perl, Python, PHP) than C/C++ should be instantly rejected by users on those grounds alone. """ I've challenged someone to beat the snippet of code below in C, C++, or assembler, for reading in one million pairs...
1
2939
by: dorandoran | last post by:
The sort on the childgrid is not working; nothing happens when I click on the each column header for sort. (I followed Satay's sample: http://www.codeproject.com/KB/aspnet/EditNestedGridView.aspx) and i am using object for datasource. please suggest. = = = default.aspx = = <%@ Page Language="C#" AutoEventWireup="true" ...
0
7459
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main...
0
7393
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7653
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7803
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
5965
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5322
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3444
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
1012
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
695
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.