How to sum two lists by items

I want to analyze the file line by line, each of which contains two integers, and then sum these values ​​in two different variables. My naive approach was this:

my $i = 0;
my $j = 0;
foreach my $line (<INFILE>)
{
    ($i, $j) += ($line =~ /(\d+)\t(\d+)/);
}

But this gives the following warning:

Useless private variable in void context

hinting that when using the + = operator, the operator starts evaluating the left side in the scalar instead of the list context (please correct me if I am wrong at this point).

Is it possible to achieve this elegantly (possibly on a single line) without resorting to arrays or intermediate variables?


Related question: How can I sum array elements in Perl?

+3
source share
4 answers

, , ($i, $j) += (something, 1) 1 $j, $i . Perl 5 , +=. :

my ($i, $j) = (0, 0);
foreach my $line (<INFILE>) {
    my ($this_i, $this_j) = split /\t/, $line;
    $i += $this_i;
    $j += $this_j;
}

, .

+6

, ( ).

: ? ( ).

split(/\t/, $line, 2)

, - ( , ):

my @a = (0, 0);
foreach my $line (<INFILE>)
{
    @a = map { shift(@a)+$_ } split(/\t/, $line, 2);
}

@lines = ("11\t1\n", " 22 \t 2 \n", "33\t3"); @a = (6, 66)

, . ! , , . perl , python, perl "" ...

+3

It is possible to swap a pair for each addition, which means that you always add to one element in each pair. (This, if necessary, generalizes to rotating multi-element arrays.)

use strict;
use warnings;

my @pair = (0, 0);

while (<DATA>) {
  @pair = ($pair[1], $pair[0] + $_) for /\d+/g;
}

print "@pair\n";

__DATA__
99 42
12 15
18 14

Output

129 71
+2
source

Here is another option:

use Modern::Perl;

my $i = my $j = 0;

map{$i += $_->[0]; $j += $_->[1]} [split] for <DATA>;

say "$i - $j";

__DATA__
1   2
3   4
5   6
7   8

Conclusion:

16 - 20
0
source

All Articles