修改然后在Perl中切片未知大小的2D数组
我知道这里已经涵盖了类似的主题,但是我遇到了一个问题,我认为这是因为我误解了如何在foreach循环的上下文中插入数组切片.我无法弄清楚我哪里出错,所以我正在寻找一些见解.
我有一个行数可变的二维数组.例如: @2DArray = (['str1',1,2,'E',val1,val2,val3] ['str2',3,4,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,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列.让攻击开始:我的新手自己哪里出错了? 解决方法
变量@Newarray_element指向整个程序中的相同内存空间,因此您在一次迭代中所做的更改会传播到您在赋值中使用该变量的先前迭代.
两个可能的修复: 一.更改变量的范围,以便在每次迭代中使用不同的内存. my @Newarray_element; foreach (@2DArray) { ... 至 foreach (@2DArray) { my @Newarray_element; ... 甚至 foreach (@2DArray) { ... my @Newarray_element = ("$projName$i",11); 二:重用@Newarray_element,但将其数据的副本分配给@Newarray的每一行.更改 push (@Newarray,@Newarray_element); 至 push (@Newarray,[ @Newarray_element ]); 后一个调用创建并向@Newarray附加一个新的匿名数组引用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |