Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

How to sort Hashes of Hashes and print results in a file

by stan131 (Acolyte)
on Mar 27, 2009 at 22:51 UTC ( [id://753797]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,
I am working with Hashes of Hashes and need to sort based value.
Here is output of my sort from Dumper
$VAR15 = '9'; $VAR16 = { '11' => '54.9503577512828', '21' => '40.4544882398113', '7' => '13.665886711539', '17' => '26.3268082750993', '2' => '16.4348644122811', '22' => '35.2357587506792', '1' => '29.5471128362965', '18' => '28.8861232027377', '23' => '19.3437720284897', }; $VAR17 = '4'; $VAR18 = { '11' => '26.7647206436788', '21' => '19.4128184125387', '7' => '6.89345884629317', '17' => '12.7682648883531', '2' => '8.44015343941174', '22' => '16.9085166076037', '1' => '15.1739716114483', '18' => '13.9203445318945', }; $VAR19 = '3'; $VAR20 = { '11' => '11.5303855045498', '21' => '9.28718107649433', '7' => '2.50040155572952', '17' => '5.93010343000324', '2' => '2.86098737229312', };
Now in this each Hash key the number of values varies.
First Key 1 has 11,21,7,17,2,22,1,18,23(where 11,21 are doc Id and each doc Id has value)
Second Key 2 has 11,21,7,17,2,22,1,18 (where 11,21 are doc Id and each doc Id has value)
I need 2 things
1) I need to sort based on document value for each key
2) Get the top 2 documents with highest docment value for each key
Your help is appreciated.
Thanks,
Stan

Replies are listed 'Best First'.
Re: How to sort Hashes of Hashes and print results in a file
by gulden (Monk) on Mar 27, 2009 at 23:50 UTC
    Is this what you want?
    #!/usr/bin/perl -w use strict; my %hash = ( 'c' => { 'e' => '54.9503577512828', '21' => '40.4544882398113', '7' => '13.665886711539', '17' => '26.3268082750993', '2' => '16.4348644122811', '22' => '35.2357587506792', '1' => '29.5471128362965', '18' => '28.8861232027377', '23' => '19.3437720284897', }, 'd' => { '11' => '26.7647206436788', '21' => '19.4128184125387', '7' => '6.89345884629317', '17' => '12.7682648883531', '2' => '8.44015343941174', '22' => '16.9085166076037', '1' => '15.1739716114483', '18' => '13.9203445318945', }, 'b' => { '11' => '11.5303855045498', '21' => '9.28718107649433', '7' => '2.50040155572952', '17' => '5.93010343000324', '2' => '2.86098737229312', } ); foreach my $k1 (sort keys %hash){ print "\n-> $k1\n"; my $count = 0; foreach my $k2 (sort {$hash{$k1}->{$b} <=> $hash{$k1}->{$a} } keys +%{$hash{$k1}} ){ print "--> $k2: $hash{$k1}->{$k2}\n"; last if $count++ > 0; } }
      Thanks a million gulden. Your script results are exactly what I want.
      I was introduced to perl only a week ago so still learning as I code more.

      Once again Thanks all for your help. Very much appreciated
      Stan
        If you want to sort "numbers" instead of "strings" for the first level keys of the hash, then replace
        foreach my $k1 (sort keys %hash){
        with
        foreach my $k1 (sort {$a <=> $b} keys %hash){
Re: How to sort Hashes of Hashes and print results in a file
by Marshall (Canon) on Mar 27, 2009 at 23:54 UTC
    I'n not sure exactly what you want, but you can adapt this...
    #!usr/bin/perl -w use strict; # a HoH my %people = ("Fred Jones" => {"AGE" =>45, "SALARY" => 90000}, "Joe Smith" => {"AGE" =>32, "SALARY" => 36400}, "Mary Arne" => {"AGE" =>29, "SALARY" => 66122}, "Ted Carney" => {"AGE" =>56, "SALARY" => 100000}, ); foreach my $key (sort keys %people) { print " $key $people{$key}->{'AGE'} $people{$key}->{'SALARY'}\n"; + } print "\nThis is the version using a hash slice\n"; foreach my $key (sort keys %people) { print " $key @{$people{$key}}{('AGE', 'SALARY')} \n"; } __END__ Prints: Fred Jones 45 90000 Joe Smith 32 36400 Mary Arne 29 66122 Ted Carney 56 100000 This is the version using a hash slice Fred Jones 45 90000 Joe Smith 32 36400 Mary Arne 29 66122 Ted Carney 56 100000
Re: How to sort Hashes of Hashes and print results in a file
by kirillm (Friar) on Mar 27, 2009 at 23:34 UTC

    Well, by definitions hashes are unordered collections. You could e.g. get an ordered list/array of key/value pairs or whatever, but they won't be hashes. Or you could use Tie::Hash::Indexed or Tie::IxHash to get ordered hashes.

    Regarding your questions, I hope you can re-phrase them.

    -- Kirill

      Ok let me rephrase. Here is my hash
      %hash{ a => {doc1=>'2.0', doc2=>'4.5', doc7=>'3.0' }, b => { doc2 => '3.5', doc10 => '6.5', doc7 => '11.4', doc20 => '0.5' } }

      Now for 'a' I need to retrieve top 2 doc with highest value.
      In this case it will be 'doc2' and 'doc7'
      In case of 'b' it will be 'doc7' and 'doc10'
      Number of docs will differ in 'a' and 'b'.
      Does this clarify my question
        I've run my script and the result was:
        -> a
        --> doc2: 4.5
        --> doc7: 3.0
        
        -> b
        --> doc7: 11.4
        --> doc10: 6.5
        
        
Re: How to sort Hashes of Hashes and print results in a file
by FunkyMonk (Chancellor) on Mar 29, 2009 at 00:41 UTC
    It's not germane to your problem, but you get prettier Data::Dumper output for hashes if you use references.

    For example, given

    use Data::Dumper; my %hash = ( 9 => { 11 => '54.9503577512828', 21 => '40.4544882398113', }, 4 => { 11 => '26.7647206436788', 21 => '19.4128184125387', } );

    print Dumper %hash yields

    $VAR1 = '4'; $VAR2 = { '11' => '26.7647206436788', '21' => '19.4128184125387' }; $VAR3 = '9'; $VAR4 = { '11' => '54.9503577512828', '21' => '40.4544882398113' };

    but print Dumper \%hash (note the backslash) produces

    $VAR1 = { '4' => { '11' => '26.7647206436788', '21' => '19.4128184125387' }, '9' => { '11' => '54.9503577512828', '21' => '40.4544882398113' } };

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-26 00:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found