performing a function on corresonding array elements
vindaloo
created: 2006-04-02 21:30:42

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;
}
Re: performing a function on corresonding array elements
created: 2006-04-02 21:53:35

#!/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.
Re^2: performing a function on corresonding array elements
created: 2006-04-02 22:29:36
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^2: performing a function on corresonding array elements
created: 2006-04-03 02:23:51
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.
Re^3: performing a function on corresonding array elements
created: 2006-04-03 08:39:43

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.
Re: performing a function on corresonding array elements
created: 2006-04-03 02:48:51

[cpan://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;

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^2: performing a function on corresonding array elements (w/o temp)
tye
created: 2006-04-03 14:23:41

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

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

- [tye]        

Re^3: performing a function on corresonding array elements (w/o temp)
created: 2006-04-03 14:26:20

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

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

perlmonks.org content © perlmonks.org and BrowserUk, codeacrobat, diotalevi, tye, vindaloo

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03