Search code examples
perldata-dumper

Perl: Sorting multilevel hash with values from inner hash when using Data::Dumper


I want to print multilevel hash using Data::Dumper. I want output to be sorted based on values from inner hash. I tried following few examples to redefine Data::Dumper::Sortkeys to sort on values for keys index but it doesn't seem to work. Here is what I tried:

use strict;
use Getopt::Long;
use Data::Dumper;
use Storable qw(dclone);
use File::Basename;
use Perl::Tidy;


my $hash = {
    key1 => {
        index => 100,
    },
    key3 => {
        index => 110,
    },
    key2 => {
        index => 99,
    },
    key5 => {
        index => 81,
    },
    key4 => {
        index => 107,
    },

};

#$Data::Dumper::Terse = 1;
$Data::Dumper::Sortkeys =
    sub {
        [sort {$b->{'index'} <=> $a->{'index'}} keys %{$_[0]}];
        };



print Dumper $hash;

I expect:

$VAR1 = {
    key5 => {
        index => 81,
    },
    key2 => {
        index => 99,
    },
    key1 => {
        index => 100,
    },
    key4 => {
        index => 107,
    },
    key3 => {
        index => 110,
    },

};

Here is what I get:

$VAR1 = {
          'key5' => {
                      'index' => 81
                    },
          'key4' => {
                      'index' => 107
                    },
          'key3' => {
                      'index' => 110
                    },
          'key2' => {
                      'index' => 99
                    },
          'key1' => {
                      'index' => 100
                    }
        };

What am I doing wrong?


Solution

  • Variables $a and $b hold the keys, so you have to use the hashref in your sortkeys sub to access the actual elements.

    use warnings;
    use strict;
    use Data::Dumper;
    
    
    my $hash = {
        key1 => {
            index => 100,
        },
        key3 => {
            index => 110,
        },
        key2 => {
            index => 99,
        },
        key5 => {
            index => 81,
        },
        key4 => {
            index => 107,
        },
    
    };
    
    #$Data::Dumper::Terse = 1;
    $Data::Dumper::Sortkeys =
        sub {
            my $h = $_[0];
            my @keys =  keys %{$h};
            [ sort {$h->{$a}{index} <=> $h->{$b}{index}} @keys]
            };
    
    print Dumper $hash;