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

Hi all,
I am trying to perform a function on an array of arrays. It will always be an array of 2 to many arrays. They are always the same sized array, which is good as I need to sum up all of the corresponding elements. I have never needed to deal with many corresdonding arrays like this before and am stumped as to how to do this. How would you attempt to do this?

#!/usr/bin/perl use strict; use warnings; my @set = ( { 'id' => '1462', 'items' => [ '9.9', '10.1', '10.3', '10.5', '10.8', '10.94' ], }, { 'id' => '1463', 'items' => [ '3.1', '4.3', '4.5', '4.6', '4.7', '4.8' ], } ); my @aoa; foreach my $hash_ref (@set) { push @aoa, $hash_ref->{items}; } my $totals = sum_up->(\@aoa); sub sum_up { my $aoa = shift; my @totals; #\@totals would look like this: #[ # '13', # '14.4', # '14.8', # '15.1', # '15.5', # '15.74' #] return \@totals; }

Replies are listed 'Best First'.
Re: performing a function on corresonding array elements
by BrowserUk (Patriarch) on Apr 03, 2006 at 01:53 UTC

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @set = ( { 'id' => '1462', 'items' => [ '9.9', '10.1', '10.3', '10.5', '10.8', '10.94' ], }, { 'id' => '1463', 'items' => [ '3.1', '4.3', '4.5', '4.6', '4.7', '4.8' ], } ); my @totals; for my $href ( @set ) { $totals[ $_ ] += $href->{items}[ $_ ] for 0 .. $#{ $href->{items} +}; } print Dumper \@totals; __END__ C:\test>540833 $VAR1 = [ '13', '14.4', '14.8', '15.1', '15.5', '15.74' ];

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Or more beautiful this way:
      use List::Util qw(sum); ... for my $href ( @set ) { $totals[ $_ ] += sum @{ $href->{items} } } ...
      It makes operations on deeply nested structures a bit more readable.

        It would be beautiful if it worked--but it does not. Where do you set the value of $_?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks, This is perfect. I appreciate using the original data structure too, that is better than transforming to arrays - (retain my id's). Cheers
Re: performing a function on corresonding array elements
by diotalevi (Canon) on Apr 03, 2006 at 06:48 UTC

    Algorithm::Loops also handles parallel looping wonderfully:

    use Algorithm::Loops qw( MapCarU ); use List::Util qw( sum ); my @items = map { $_->{items} } @sets; my @totals = MapCarU { sum( @_ ) } @items;

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      And, of course, it also works without the temporary array variable:

      ... my @totals= MapCarU { sum( @_ ) } map $_->{items}, @sets;

      - tye        

        Which is exactly how I'd write it for myself. I thought I'd opt to be clearer.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊