How to sort by value from a second level hash in Perl?

my $hash_ref = {
    one   => { val => 1, name => 'one'  },
    three => { val => 3, name => 'three'},
    two   => { val => 2, name => 'two'  },
};

      

I would like to sort $hash_ref

so that foreach orders them with

$hash_ref->{$key}->{'val'}

one
two
three

      

Any suggestions?

+2


source to share


4 answers


@sorted_list

- an array of references to sorted hash elements:

 @sorted_list = sort { $a->{'val'} <=> $b->{'val'} } values %{$unsorted_hash_ref};

      

You can use it like this:



#!/usr/bin/perl

my $hash_ref = {
    one   => { val => 1, name => 'one' },
    three => { val => 3, name => 'three' },
    two   => { val => 2, name => 'two' },
};

foreach $elem ( sort { $a->{'val'} <=> $b->{'val'} } values %{$hash_ref} ) {
    print "$elem->{'val'} : $elem->{'name'}\n";
}

      

Output:

1 : one
2 : two
3 : three

      

+8


source


There is no specific order in hash tables. However, you can sort the keys in an array and use them to iterate through the hash:

my $hash_ref = {
    one => { val => 1, name => 'one'},
    three => { val => 3, name => 'three'},
    two => { val => 2, name => 'two'},
};

use strict;
use warnings;
use Lingua::EN::Words2Nums;

foreach my $key (sort { words2nums($a) <=> words2nums($b) } keys %$hash_ref)
{
    # do something with $hash_ref->{$key}
    print "processing key $key.\n";
}

      



You can define whatever you like as the sorting method; see perldoc -f sort for details . Conversion from ordinal numeric text to arithmetic values ​​is done with Lingua :: EN :: Words2Nums (these are also cardinal numbers).

0


source


use strict;
use warnings;

my %hash_ref = (
one   => { val => 1, name => 'one'  },
three => { val => 3, name => 'three'},
two   => { val => 2, name => 'two'  },
);

foreach my $key(sort {$hash_ref{$a}{val} <=> $hash_ref{$b}{val}} keys %hash_ref) {
my $value = $hash_ref{$key}{val};
my $name = $hash_ref{$key}{name};
print "$name -> $value\n";
}

output:
one -> 1
two -> 2
three -> 3

      

0


source


#!/usr/bin/perl


my $hash_ref = (
                one   => {val => 1,  name => "one"},
                three => {val => 3,  name => "three"},
                two   => {val => 2,  name => 'two'},
               );

foreach $elem( sort {$$hash_ref{$a}{val} <=> $$hash_ref{$b}{val}} keys %$hash_ref){
    my $value = $hash_ref->{$elem}{val};
    my $name = $hash_ref->{$elem}{name};
    print "$name -> $value\n";
}

OutPut:
one -> 1
two -> 2
three -> 3

      

0


source







All Articles