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?
, , ($i, $j) += (something, 1) 1 $j, $i . Perl 5 , +=. :
($i, $j) += (something, 1)
1
$j
$i
+=
my ($i, $j) = (0, 0); foreach my $line (<INFILE>) { my ($this_i, $this_j) = split /\t/, $line; $i += $this_i; $j += $this_j; }
, .
, ( ).
: ? ( ).
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)
@lines = ("11\t1\n", " 22 \t 2 \n", "33\t3");
@a = (6, 66)
, . ! , , . perl , python, perl "" ...
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
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