Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

HoH Sorting by value

by Anonymous Monk
on Oct 23, 2002 at 17:29 UTC ( [id://207451]=perlquestion: print w/replies, xml ) Need Help??

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

I have a Hash of Hashes that I need to sort by a value. I have been checking out other posts, the perldocs, and trying different things but can't quite get it.

My data is as follows:
{ss_number}
 {employee_number}
  {years_employed}

I need to sort numerically according to the values in the years_employed.

Replies are listed 'Best First'.
Re: HoH Sorting by value
by broquaint (Abbot) on Oct 23, 2002 at 17:36 UTC
    This should give you a sorted list of keys for your HoHoH
    my @sorted = sort { $hash{$a}->{employee_number}->{years_employed} <=> $hash{$b}->{employee_number}->{years_employed} } keys %hash;
    HTH

    _________
    broquaint

      Is there any way to do this without creating a new array of the sorted values? I really do appreciate the help, but that wasn't what I was hoping for.

        Hashes themselves cannot be sorted -- the closest one can get is to sort either the keys or the values of the hash, then iterate through them. See perldoc -q "sort a hash"

        perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

        Take broquaint's answer, remove the assignment, add a loop and a print. Job done.

        Or do you just want the code:

        my %hash; while (<DATA>) { my @data = split; $hash{$data[0]}->{employee_number} = $data[1]; $hash{$data[0]}->{years_employed} = $data[2]; } foreach (sort { $hash{$a}->{years_employed} <=> $hash{$b}->{years_employed} } keys %hash) { print "$_ $hash{$_}->{employee_number} $hash{$_}->{years_employed}\ +n"; }; __DATA__ SS123 EMP123 3 SS234 EMP124 2 SS456 EMP125 1
        prints
        SS456 EMP125 1 SS234 EMP124 2 SS123 EMP123 3

        rdfield

Re: HoH Sorting by value
by Anonymous Monk on Oct 23, 2002 at 18:01 UTC
    Maybe I wasn't specific enough in my original question. Given the data above, I would like to print each ss_number, employee_number, & years_employed only sorted by years_employed. In other words, I would like this, only sorted:

    foreach my $ss_number {keys %my_hash} { print "$my_hash{$ss_number}{$employee_number}\n"; }
      Your data structure doesn't look right to me, unless you really want to have multiple employee_numbers per ss_number.

      Probably you want a hash with ss_number as the key and the value as either an array ref or hash ref with all the values associated with that ss_number. E.g.

      $myhash{'555236801'} = [3035, 2]; or $myhash{'555236801'} = { empno => 3035, years => 2 };
      Anyway, one easy way to get what you want is like this (at least on Unix (using the latter data structure:
      open SORTEDOUT, "|sort +2" or die "cannot open sort: $!\n"; for (keys %myhash) { print SORTEDOUT $_, " ", $myhash{$_}{empno}, " ", $myhash{$_}{year +s}, "\n"; } close (SORTEDOUT) or die "Error on sort: $!\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://207451]
Approved by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2024-12-08 02:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which IDE have you been most impressed by?













    Results (50 votes). Check out past polls.