3

それぞれ 2 つの整数を含むファイルを 1 行ずつ解析し、これらの値を 2 つの異なる変数で合計します。私の素朴なアプローチは次のようなものでした:

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

ただし、次の警告が表示されます。

void コンテキストでのプライベート変数の無駄な使用

+= 演算子に頼ると、リストコンテキストではなくスカラーで左辺の評価がトリガーされることを示唆しています (この点で間違っている場合は修正してください)。

配列や中間変数に頼らずに、これをエレガントに (おそらく 1 行で) 達成することは可能ですか?


関連する質問: Perl で要素ごとに配列を合計するにはどうすればよいですか?

4

4 に答える 4

6

いいえ、それは、式($i, $j) += (something, 1)が追加のみとし1て解析され、無効なコンテキストにぶら下がっているためです。Perl 5 には、 などの代入演算子のハイパー演算子や自動圧縮はありません。これは機能します:$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;
}

列の名前付き変数の代わりに複合データ構造を使用することで、繰り返しを回避できます。

于 2012-05-23T10:15:46.937 に答える
3

まず第一に、ペアごとに配列を追加する方法が機能しません (自分で投稿した関連する質問にいくつかのヒントがあります)。

解析部分については、行を分割するだけではどうですか? 行が適切にフォーマットされている場合 (空白は問題になりません)。

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)

回答の分割部分を使用することをお勧めしますが、合計部分は使用しないでください。複数の行を使用しても問題はありません。意図が明確になるのであれば、セリフは 1 つよりも多い方がよいでしょう。しかし、最近はほとんど perl を使用しておらず、代わりに python を使用しているため、私の perl コーディング スタイルが「悪い」影響を与えている可能性があります...

于 2012-05-23T10:37:24.440 に答える
2

追加ごとにペアを交換することは十分に可能です。つまり、常に各ペアの同じ要素に追加することになります。(これは、必要に応じて多要素配列の回転に一般化されます。)

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

出力

129 71
于 2012-05-23T13:42:06.743 に答える
0

別のオプションは次のとおりです。

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

出力:

16 - 20
于 2012-05-23T12:52:01.447 に答える