修改然后在Perl中切片未知大小的2D数组

MCo*_*Cor 5 perl foreach slice multidimensional-array

我知道这里已经涵盖了类似的主题,但是我遇到了一个问题,我认为这是因为我误解了如何在foreach循环的上下文中插入数组切片.我无法弄清楚我哪里出错,所以我正在寻找一些见解.

我有一个行数可变的二维数组.例如:

@2DArray = (['str1', 1, 2, 'E', val1, val2, val3]
            ['str2', 3, 4, 'E', val4, val5, val6]
            ['str4', 5, 6, 'F', val7, val8, val9])   
Run Code Online (Sandbox Code Playgroud)

我想构建一个带有附加列的新数组,只有当它们在第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;
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,我得到的是:

#(original) col nums:      0       1    2    5    3

                  test2    str2    3    4    +    2    STR    11    11
                  test2    str2    3    4    +    2    STR    11    11
Run Code Online (Sandbox Code Playgroud)

也就是说,我的新数组将在原始数组中的每一行都有一行,第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;
Run Code Online (Sandbox Code Playgroud)

我得到了我期望的输出:

                  *            &
str1    1    2    1    val1    +    val3
str2    3    4    2    val4    +    val6
Run Code Online (Sandbox Code Playgroud)

标有*和&的列是修改后的第3列和第5列.让攻击开始:我的新手自己哪里出错了?

mob*_*mob 4

该变量@Newarray_element在整个程序中指向相同的内存空间,因此您在一次迭代中所做的更改将传播到您在赋值中使用该变量的先前迭代。

两个可能的修复:

。更改变量的范围,以便它在每次迭代中使用不同的内存。改变

my @Newarray_element;
foreach (@2DArray) {
    ...
Run Code Online (Sandbox Code Playgroud)

foreach (@2DArray) {
    my @Newarray_element;
    ...
Run Code Online (Sandbox Code Playgroud)

甚至

foreach (@2DArray) {
    ...
    my @Newarray_element = ("$projName$i", @$_[0,1,2,5,3], 'STR', 11, 11);
Run Code Online (Sandbox Code Playgroud)

:重用@Newarray_element但将其数据的副本分配@Newarray给. 改变

push (@Newarray, \@Newarray_element);
Run Code Online (Sandbox Code Playgroud)

push (@Newarray, [ @Newarray_element ]);
Run Code Online (Sandbox Code Playgroud)

后一个调用创建一个新的匿名数组引用并将其附加到@Newarray.