dilip.renkila has asked for the wisdom of the Perl Monks concerning the following question:

Hi All, Below is my hash.In it for example'2' means id , '25' describes interface index ,'i' and 'o' depicts respective in and out octets. I will be probing and getting the above hash for every 5 min and i want to update it in RRD Database and also i have to obey this condition" each id we have to use only one rrd file" (I Used RRD::Editor). By using hashes without sorting they will get updated irregularly in rrd database and i tried the below code and it is showing error
HASH: %update = { '2'=>{ '25' => { 'i' => 5000000, 'o' => 5000000 }, '4' => { 'o' => 5000000, 'i' => 5000000 } } }; CODE: foreach my $i (keys %update) { print Dumper($i); my $rrdfile="$pwd/$i.rrd"; my $rrd = RRD::Editor->new(); $string=(); $updateRRD="N"; foreach my $j(keys %{$update{$i}}) { foreach my $k(keys %{$update{$j}}) { $updateRRD=$updateRRD.":".$update{$i}{$j}{$k}; } } print Dumper ($updateRRD); $rrd->update($updateRRD); } Error: expected 9 data source readings (got 0) from N
Please help me?

Replies are listed 'Best First'.
Re: sorting hash of hashes
by Athanasius (Archbishop) on Oct 28, 2015 at 13:38 UTC

    Hello dilip.renkila, and welcome to the Monastery!

    (1) Your third foreach loop has keys %{$update{$j}} where it should have keys %{$update{$i}{$j}}.

    (2) If you want the output to be sorted by key, that’s easy: just add sort in each foreach loop:

    foreach my $i (sort keys %update) { ... foreach my $j (sort keys %{$update{$i}}) { foreach my $k (sort keys %{$update{$i}{$j}}) { ... } } }

    But note that this “sorts in standard string comparison order.” (see sort) To sort numerically, you will need to use:

    sort { $a <=> $b } keys ...

    where the keys are numeric.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Is this sort works also for characters? Thank you for your reply
        Is this sort works also for characters?

        Yes, by default, sort sorts alphabetically. Consider:

        12:36 >perl -Mstrict -wE "my @array = ('c', 'bb', 'aaa'); say for sort + @array;" aaa bb c 12:37 >

        Here sort puts 'aaa' first, because 'a', its first character, comes alphabetically before 'b' and 'c'. Similarly:

        12:37 >perl -Mstrict -wE "my @array = ('3', '22', '111'); say for sort + @array;" 111 22 3 12:39 >

        puts '111' first because '1' comes alphabetically before '2' and '3'.

        Note that sort @array is shorthand for sort { $a cmp $b } @array; cmp compares alphabetically. To sort numerically, use <=> instead of cmp:

        12:39 >perl -Mstrict -wE "my @array = ('3', '22', '111'); say for sort + { $a <=> $b } @array;" 3 22 111 12:43 >

        See:

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: sorting hash of hashes
by Laurent_R (Canon) on Oct 28, 2015 at 14:57 UTC
    Your initial data structure appears not to be a hash (despite the initial % sigil), but a hash reference, so that looping on the keys will fail.

    Is this data structure something that you built yourself, or do you get it from another program or a subroutine/module call that you have not shown?

    If you're building it yourself, then change it to something like:

    %update = ( '2'=>{ '25' => { 'i' => 5000000, 'o' => 5000000 }, '4' => { 'o' => 5000000, 'i' => 5000000 } } );
    (Parens instead of curlies for the external delimiters.)

    If you're getting that hash ref data structure from somewhere else (e.g. another program or another part of your program), then you probably need to change your foreach loops to use a hashref instead of a hash. For example, change the foreach my $i (keys %update) line to something that uses an hash ref rather than a hash, for example, assuming your data hashref is $update, something like:

    foreach my $i (keys %$update) { #...
Re: sorting hash of hashes
by GotToBTru (Prior) on Oct 28, 2015 at 12:41 UTC

    Your inmost loop looks suspicious - you repeat the same expression as its predecessor.

    I usually find it helps when dealing with a complicated datastructure to run the program in the debugger. That way you can experiment with syntax to get the part you want.

    Dum Spiro Spero
Re: sorting hash of hashes
by shadowsong (Pilgrim) on Oct 28, 2015 at 22:56 UTC

    Hi dilip.renkila

    In addition to what Athanasius has outlined re: your inner-most foreach loop and Laurent_R re: your initial data structure, here is a snippet of code and its output to help with the syntax of sort

    Code

    #!/usr/bin/perl -lw use strict; my %update = ( '2' => { '25' => { 'i' => 5000025, 'o' => 5000025 }, '4' => { 'o' => 5000004, 'i' => 5000004 }, '19' => { 'i' => 5000019, 'o' => 5000019 }, '2' => { 'o' => 5000002, 'i' => 5000002 }, }, '6' => { '7' => { 'i' => 5000007, 'o' => 5000007 }, '13' => { 'o' => 5000013, 'i' => 5000013 }, } ); for my $id (sort {$a <=> $b} keys %update) { for my $index (sort {$a <=> $b} keys %{$update{$id}}) { print "$update{$id}->{$index}->{i},$update{$id}->{$index}->{o}"; } } __END__

    Output

    5000002,5000002 5000004,5000004 5000019,5000019 5000025,5000025 5000007,5000007 5000013,5000013

    Good Luck!