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

Hey all, i am writing a report utility, and ended up with a sort question, regarding using sort functions. Im familiar with defining my own sort function or inline, i just cant figure out how to get this sort into a function properly.

I have a hash whose keys are some internal code. They values are hashrefs, each with 2 keys, "dept" and "count". "dept" is a count of how many departments use the code, and count is a total of the people in all those departments. I want everything sorted based on how many departments use each code.
Here's how i do it with an inline sort:
foreach my $code ( sort { $dept_n_code{$a}->{'dept'} <=> $dept_n_code{$b}->{'dept'} } keys %dept_n_code ) { my $desc = $code_map->{$code}; my $out_line = pack $pack_template, $code, $desc, $dept_n_code{$code}->{'dept'}, $dept_n_code{$code}->{'count'}; print REPORT "$out_line\n"; }
Sorry about the odd code formatting, there are rather long lines for this forum.

Anyway, i couldnt figure out a reasonable way to put the sort into its own function, so that i could re-use it. Perhaps the problem is how i have structured the data.
Thanks,
shemp

Replies are listed 'Best First'.
Re: Sort function issue
by tall_man (Parson) on Jun 24, 2003 at 18:36 UTC
    Why wouldn't this work:
    sub by_dept_total { return $dept_n_code{$a}->{'dept'} <=> $dept_n_code{$b}->{'dept'}; } sort by_dept_total ...
      The reason could be:
      use strict; use warnings; main(); xyz(); sub main{ my $h; foreach (1..20){ $h->{$_} = int rand (100); } foreach (sort by_val keys %{$h}){ print "$_","\t",$h->{$_}; } } sub xyz { my $k; foreach (1..20){ $k->{$_} = int rand (100); } foreach (sort by_val keys %{$k}){ print "$_","\t",$k->{$_}; } } sub by_val { $h->{$a} <=> $h->{$b}; }
      artist
        In that case:
        use strict; use warnings; main(); xyz(); sub main{ my $h; foreach (1..20){ $h->{$_} = int rand (100); } my $by_val = make_sort($h); foreach (sort $by_val keys %{$h}){ print "$_","\t",$h->{$_}; } print "\n"; } sub xyz { my $k; foreach (1..20){ $k->{$_} = int rand (100); } my $by_val = make_sort($k); foreach (sort $by_val keys %{$k}){ print "$_","\t",$k->{$_}; } print "\n"; } sub make_sort { my $dat = shift; return sub { $dat->{$a} <=> $dat->{$b} }; }
Re: Sort function issue
by jmanning2k (Pilgrim) on Jun 25, 2003 at 20:20 UTC
    To simplify on the above solutions...
    You can use the closure method, but that is really making a new sort function for each hash you have.
    What you want is a function that takes a hash, and returns the sorted keys.
    sub sorted_by_dept(\%) { my $href = shift; my @sorted = map {$_->[0] } sort {$a->[1] <=> $b->[1] } map { [$_, $href->{$_}->{dept}] } keys %$href; return @sorted; }
    To break this down, follow it backwards. Starting at keys -- for each key in the hash, the last map builds pairs of values. The first number of the pair is the end value you want. The second number of the pair is what you want to sort by.
    The sort command sorts by the second number, and the upper map looks up the original key value for you.
    You then have a sorted list of keys you can use in a foreach.

    Hope this helps,
    ~jmanning2k