ここで同様のトピックが取り上げられていることは知っていますが、foreach ループのコンテキストで配列スライスがどのように補間されるかについての私の誤解から生じると思われる問題に直面しています。どこが間違っているのかわからないので、洞察を探しています。
行数が可変の 2D 配列があります。例として:
@2DArray = (['str1', 1, 2, 'E', val1, val2, val3]
['str2', 3, 4, 'E', val4, val5, val6]
['str4', 5, 6, 'F', val7, val8, val9])
列 3 に文字列 'E' が含まれている場合にのみ、元の配列の行の一部を組み込む列を追加して、新しい配列を作成したいと考えています。さらに、新しい配列に組み込みたい行については、列のサブセットのみが必要で、そのサブセットを別の順序で並べたい。最終的な目標は、下流のスクリプトが必要とする正しい形式の出力を生成することです。
これが私の試みです:
my $projName = 'test';
my $i = 1;
my @Newarray
my @Newarray_element;
foreach (@2DArray) {
if (${$_}[3] eq 'E') {
${$_}[3] = $i;
${$_}[5] = '+';
@Newarray_element = ("$projName$i", @$_[0,1,2,5,3], 'STR', 11, 11);
$i++;
push (@Newarray, \@Newarray_element);
}
next;
}
print (join("\t", @$_), "\n") for @Newarray;
ただし、それを行うと、次のようになります。
#(original) col nums: 0 1 2 5 3
test2 str2 3 4 + 2 STR 11 11
test2 str2 3 4 + 2 STR 11 11
つまり、私の新しい配列には、列 3 に「E」がある元の配列のすべての行の行がありますが、各行には、ループによって処理される最後の行の値が入力されます。
問題が foreach ループで 2D 配列をスライスすることに関係していると思う理由は、単に 2D 配列をループして、列 3 に「E」があるすべての行を見つけ、他の列のいくつかの値を変更するかどうかを知っているからです。それらの行について、それを新しい配列に返すと、すべて完全に機能します。つまり、代わりにこれを行うと:
my @Newarray;
my $i = 1;
foreach (@2Darray) {
if (${$_}[3] eq "E") {
${$_}[3] = $i;
${$_}[5] = '+';
$i++;
push (@Newarray, \@$_);
}
next;
}
print (join("\t", @$_), "\n") for @Newarray;
期待どおりの出力が得られます。
* &
str1 1 2 1 val1 + val3
str2 3 4 2 val4 + val6
ここで、* と & でマークされた列は、変更された列 3 と 5 です。