fruitbeeriswrong has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I hope I won't commit any faux pas' on my first request for guidance!! But here goes... I'm trying to order an array of records. The code runs but the array remains un-ordered. Am i missing something obvious? Here is my code (well not my code but adapted from an example here -> http://www.cs.pitt.edu/~ramirez/cs1520/perl/ex9.pl)
#!/usr/bin/perl -w # "-w" turns on all sorts of warnings about probabl +e errors. use diagnostics; # optional; causes warnings to be explained in grea +ter detail. use strict; my @workers; my $h = {name => "Herb", salary => 250000, job => "doctor"}; push(@workers, $h); $h = {name => "Marge", salary => 400000, job => "ceo"}; push(@workers, $h); $h = {name => "Ingmar", salary => 50000, job => "painter"}; push(@workers, $h); print "\n Unsorted list\n"; show(@workers); my @sort2 = sort by_sal @workers; print "\n Sorted by salary\n"; show(@sort2); sub by_sal { my %worka = %$a; my %workb = %$b; my $empa = $worka{"salary"}; my $empb = $workb{"salary"}; if ($empa < $empb) { return -1; } elsif ($empa == $empb) { return 0; } elsif ($empa > $empb) { return 1; } } sub show { foreach my $workref (@workers) { my %work = %$workref; print "Name: ", $work{"name"}, "\t"; print "Salary: ", $work{"salary"}, "\t"; print "Job: ", $work{"job"}, "\n"; } }

Replies are listed 'Best First'.
Re: Sorting an array of records
by ikegami (Patriarch) on Aug 30, 2005 at 18:13 UTC

    You're always showing @workers, regardless of show's arguments.

    Change
    foreach my $workref (@workers)
    to
    foreach my $workref (@_)

    Actually, that can be optimized. You should actually pass an array reference to show instead of a list:

    show(\@workers); ... show(\@sort2); ... sub show { my ($array) = @_; foreach my $workref (@$array) { ... } }

    I was about to update my node with other inefficiencies, but others have already mentioned them. Avoid copying the hash (%worka = %$a) and have a look at the <=> equality operator.

      Thanks, thats brilliant. If you listen closely you can here the sound of me kicking myself.
Re: Sorting an array of records
by tlm (Prior) on Aug 30, 2005 at 18:19 UTC

    ikegami already answered your question, but as a comment on style, in this case I think this would be easier to read:

    my @sort2 = sort { $a->{ salary } <=> $b->{ salary } } @workers;

    the lowliest monk

      Thanks, your code snippet works a treat.
Re: Sorting an array of records
by Codon (Friar) on Aug 30, 2005 at 18:59 UTC

    One more comment on style: you are assigning an anonymous hash to a variable to push the hash onto an array. Why not just directly push the anonymous hash onto the array:

    my @workers; push @workers, {name => "Herb", salary => 250000, job => "doctor"}; push @workers, {name => "Marge", salary => 400000, job => "ceo"}; push @workers, {name => "Ingmar", salary => 50000, job => "painter"};
    It's minor (in this context), I know, but those little bits of memory consumed by things like $h hanging around can add up over the life of a program.

    Ivan Heffner
    Sr. Software Engineer, DAS Lead
    WhitePages.com, Inc.
Re: Sorting an array of records
by BaldPenguin (Friar) on Aug 30, 2005 at 18:21 UTC
    I was going to post the same as above, but now I won't. However, I was wondering why you wrote a subroutine for the sort as opposed to
    my @sort2 = sort { $a->{'salary'} <=> $b->{'salary'} } @workers;

    Don
    WHITEPAGES.COM | INC
    Everything I've learned in life can be summed up in a small perl script!