CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
Search Posts SEARCH
Who's Online WHO'S
Log in LOG

Home: Perl Programming Help: Intermediate:
Sorting arrays



Apr 24, 2005, 7:20 AM

Post #1 of 3 (732 views)
Sorting arrays Can't Post

How can I sort an array by a variable that is not at the beginning? For example, an array = ($item1,$item2,$item3) and it split by "|". How can I sort this array without using a foreach and creating a new array with the third item at the beginning. This is complicated, takes more power, and uses a lot of code because I need to be able to sort data by about 5 different variables. Is there a simple way to sort this by a variable deeper into the array than the first item?
Wink Wink
Visit my new site devoted to reviewing the latest pocketpc products and news that I built in cgi-perl!


Apr 24, 2005, 12:19 PM

Post #2 of 3 (730 views)
Re: [benn600] Sorting arrays [In reply to] Can't Post

simple is a relative term, but if you read the FAQ's forum there is one about sorting data using any of the fields in your list.;sb=post_latest_reply;so=ASC;forum_view=forum_view_collapsed;;page=unread#unread

this question is asked often so a search of the froums should also show many examples of how to sort lists.

Thaumaturge / Moderator

Apr 25, 2005, 2:49 AM

Post #3 of 3 (725 views)
Re: [benn600] Sorting arrays [In reply to] Can't Post

It's not very clear what you're asking so if I'm making invalid assumptions please feel free to correct me.

I'm assuming that you have a data structure that looks something like like:

my @data = ( 

And you (for example) want to sort it by the numeric field.

The naive way is to write a simple sort subroutine like this.

sub my_sort { 
my @a = split /\|/, $a;
my @b = split /\|/, $b;

return $a[2] <=> $b[2];

my @sorted_data = sort my_sort @data;

This works, but can be a little inefficient. You might be better off using something like the Schwartzian Transform.

my @sorted_data = 
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, [ split /\|/ ]] } @data;

Another approach would be to rebuild your data structure to better reflect what it is actually storing - i.e. an array of hashes.

my @cols = qw(f_name, l_name, score); 
foreach (@data) {
my %rec;
@rec{@cols} = split /\|/, $_;
$_ = \%rec;

You can then write code that actually accesses the correct part of the hash directly.

my @sorted_data = sort { $a->{score} <=> $b->{score} } @data;

See the documentation on "sort" and any good Perl book's section of sorting for more details.

Dave Cross, Perl Hacker, Trainer and Writer
Get more help at Perl Monks


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives