I have the following hashed structure

$chainStorage{$R1}{$S1}{$C1}{@A1}

$chainStorage = {
'ACB' => {
'E' => '06' => [100, 200, 95]
'B' => '23' => [20, 1000, 05, 30]
},
'AFG' => {
'C' => '24' => [18, 23, 2300, 3456]
},
'HJK' => {
'A' => '12' => [24, 25, 3200, 5668]
'D' => '15' => [168]
}
};

For example, ACB corresponds to two arrays,[100, 200, 95] and [20, 1000, 05, 30];
while ‘E’ corresponds to [100, 200, 95] only.

Right now, I need to add all of the elements in the array corresponding to the first-level key, e.g., ‘ACB’, together.

In other words, in another hash structure, I want ACB corresponds to
100+200+95 +20+1000+05+30 = 1450

How to implement this functionality over $chainStorage

Recommended Answers

All 2 Replies

Use code tags instead of quote tags to preserve formatting.

The code you've posted doesn't describe the structure you've said it does. => is just syntactic sugar for a comma, so $chainStorage->{ACB} is

{
    E => '06',
    [100, 200, 95] => 'B',
    '23' => [20, 1000, 5, 30],
}

Assuming you meant the following (formatting added)...

$chainStorage = {
    ACB => {
        E => { '06' => [100, 200, 95] },
        B => { '23' => [20, 1000, 5, 30] },
    },
    AFG => {
        C => { '24' => [18, 23, 2300, 3456] },
    },
    HJK => {
        A => { '12' => [24, 25, 3200, 5668] },
        D => { '15' => [168] },
    },
};

... then you still have kind of an odd situation because your tertiary (third-layer) hashes never have more than one key and one value. If that's always the case it'd probably be better to think of a different way to store them. You might, for instance, make the tertiary key the first element of the list, like this:

ACB => {
        E => ['06', 100, 200, 95],
        B => ['23', 20, 1000, 5, 30],
    },

Then use something like this to add the elements:

my $href = $chainStorage->{ACB};

my $sum = 0;
foreach my $aref (values %$href) {
        my @ary = @$aref;
        @ary = @ary[1..$#ary]; # I had to slice the first element back out
        $sum += $_ foreach (@ary);
}

If you can't restructure your data like this, it'll be an extra step to pull the array out of the interior hashref, but that shouldn't be too much of a stretch... Without making unwarranted assumptions about your data structure, I can't give you any more, but maybe this is enough to go on.

Building on Trentacle's first correction of your data structure you could try the following:

#!/usr/bin/perl;
use strict;
use warnings;
use Data::Dumper;

my $chainStorage = {
    ACB => {
        E => { '06' => [100, 200, 95] },
        B => { '23' => [20, 1000, 5, 30] },
    },
    AFG => {
        C => { '24' => [18, 23, 2300, 3456] },
    },
    HJK => {
        A => { '12' => [24, 25, 3200, 5668] },
        D => { '15' => [168] },
    },
};

my %results;

foreach my $flk(keys %$chainStorage){
    $results{$flk} = 0;
    
    foreach my $slk(keys $$chainStorage{$flk}){
        foreach my $tlk(keys $$chainStorage{$flk}{$slk}){
            foreach my $aref ($$chainStorage{$flk}{$slk}{$tlk}){
                foreach my $elem(@$aref){
                    $results{$flk} += $elem;
                }
            }
        }
    }
}

print Dumper(\%results);

Outputs

$VAR1 = {
          'AFG' => 5797,
          'HJK' => 9085,
          'ACB' => 1450
        };
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.