如何在一个数组引用的数组中删除特定的数组?

3

我想要删除数组引用中的特定数组。为此,我循环遍历数组引用,并寻找匹配项。如果找到匹配项,我尝试通过将其设置为等于“nothing”来删除该特定数组引用。在我编写的脚本中发生了两件奇怪的事情: 1)代码似乎在处理匹配项之前就能够识别感兴趣的数组与数组引用之间的匹配存在。 2)在尝试删除一个特定的数组引用时,我最终删除了所有引用。以下是我的代码:

#!/usr/bin/perl
use strict;
use warnings;

my @array_1 = ('CTCTTGCCTCAATCATATAT', 'CTCTTGCCTCATTGATATAT', 'CTCTTGCCTCAATCATATAT', 'CACTTGCCTCAATGAAATTT', 'GTCTTGCCTCATTGATAAAT', 'CACTTGCCTCAATGTAATAT', 'CTCTTCCCTCAATGATTTAA', 'CACTTGCCTCAATGATATAT', 'CTCTTGCCTCATTGATATAT', 'CTCTTGCCTCAATGTTATAT', 'CTGATGCCTCATTGATATAT', 'CTGTTGGCTCAATCATATAT');
my @array_2 = ('CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', 'CACTTGCCTCAATGATATAT', 'CTCTTCCCTCAATGATTTAA', 'CTCTTGCCTCAATGTTATAT', 'CTGTTGGCTCAATCATATAT', 'CTGATGCCTCATTGATATAT', 'GTCTTGCCTCATTGATAAAT', 'CACTTGCCTCAATGAAATTT');
my @array_3 = ('TATCATTGCCCAATTTAAGT', 'TTTCTTTGCCGAATATAAGT', 'TTTCTATGCGCAATTTAAGT', 'TATCTTAGCCCAATTTTTGT', 'TTTCTTTGCCCAATATATGT', 'TTTCTTTGGCCTATTTTTGT', 'TTTGTTTGGCCATTTTATGT', 'TTTCTTTGGCGAATTTATCT', 'TTTCATTGCCCAATTATTGT', 'TTTCTTTGCCCAAAATAAGT', 'CACTTGCCTCAATGTAATAT');
my @array_4 = ('TTTCTTTGCCCAATATATGT', 'TTTCTTTGCCGAATATAAGT', 'TTTCTATGCGCAATTTAAGT', 'TATCTTAGCCCAATTTTTGT', 'TTTCTTTGGCCTATTTTTGT', 'TTTGTTTGGCCATTTTATGT', 'TTTCTTTGGCGAATTTATCT', 'TTTCATTGCCCAATTATTGT', 'TATCATTGCCCAATTTAAGT', 'TTTCTTTGCCCAAAATAAGT', 'CTCTTGCCTCAATCATATAT');

my $array_1_ref = \@array_1;
my $array_2_ref = \@array_2;
my $array_3_ref = \@array_3;
my $array_4_ref = \@array_4;

my @array_to_delete = ('CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', 'CACTTGCCTCAATGATATAT', 'CTCTTCCCTCAATGATTTAA', 'CTCTTGCCTCAATGTTATAT', 'CTGTTGGCTCAATCATATAT', 'CTGATGCCTCATTGATATAT', 'GTCTTGCCTCATTGATAAAT', 'CACTTGCCTCAATGAAATTT');
print "Array to delete: ", join(", ", @array_to_delete), "\n";

my @array_of_array_references = ($array_1_ref, $array_2_ref, $array_3_ref, $array_4_ref);

for (my $i = 0; $i <= $#array_of_array_references; $i++){
    print "\n", "A single array in the array of array references: ", join(", ", @{$array_of_array_references[$i]}), "\n";
    if (@array_to_delete = @{$array_of_array_references[$i]}){
            print "Both arrays match!\n";
            @{$array_of_array_references[$i]} = ();
    }
}
for (my $i = 0; $i <= $#array_of_array_references; $i++){
    print "\n", "A single array in the array of array references after removing one: ", join(", ", @{$array_of_array_references[$i]}), "\n";
}

输出结果为:
Array to delete: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT

A single array in the array of array references: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT
Both arrays match!

A single array in the array of array references: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT
Both arrays match!

A single array in the array of array references: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT
Both arrays match!

A single array in the array of array references: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT
Both arrays match!

A single array in the array of array references after removing one: 

A single array in the array of array references after removing one: 

A single array in the array of array references after removing one: 

A single array in the array of array references after removing one: 

期望的输出结果:

Array to delete: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT

A single array in the array of array references: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT

A single array in the array of array references: CACTTGCCTCAATGTAATAT, TATCATTGCCCAATTTAAGT, CACTTGCCTCAATGATATAT, CTCTTCCCTCAATGATTTAA, CTCTTGCCTCAATGTTATAT, CTGTTGGCTCAATCATATAT, CTGATGCCTCATTGATATAT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGAAATTT
Both arrays match!

A single array in the array of array references: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT

A single array in the array of array references: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT

A single array in the array of array references after removing one: CTCTTGCCTCAATCATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATCATATAT, CACTTGCCTCAATGAAATTT, GTCTTGCCTCATTGATAAAT, CACTTGCCTCAATGTAATAT, CTCTTCCCTCAATGATTTAA, CACTTGCCTCAATGATATAT, CTCTTGCCTCATTGATATAT, CTCTTGCCTCAATGTTATAT, CTGATGCCTCATTGATATAT, CTGTTGGCTCAATCATATAT

A single array in the array of array references after removing one: TATCATTGCCCAATTTAAGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGCCCAATATATGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TTTCTTTGCCCAAAATAAGT, CACTTGCCTCAATGTAATAT

A single array in the array of array references after removing one: TTTCTTTGCCCAATATATGT, TTTCTTTGCCGAATATAAGT, TTTCTATGCGCAATTTAAGT, TATCTTAGCCCAATTTTTGT, TTTCTTTGGCCTATTTTTGT, TTTGTTTGGCCATTTTATGT, TTTCTTTGGCGAATTTATCT, TTTCATTGCCCAATTATTGT, TATCATTGCCCAATTTAAGT, TTTCTTTGCCCAAAATAAGT, CTCTTGCCTCAATCATATAT

2
当你说“删除”时,你是指完全移除该元素(以便最终数组元素减少一个),还是用空字符串或undef来替换它(就像问题本身所说的)?(2) 你的数组通常有多大? - undefined
1
If语句使用==eq而不是单个的= :) - undefined
嗨Zdim。我希望完全删除这个元素。我的数组大小不同,但平均可以有几百到几千个元素。谢谢你的问题。 - undefined
嗨Gerhard。谢谢你的信息。我会更新我的代码和问题。 - undefined
1个回答

3

诸如此类的代码

if (@array_1 == @array_2)   # same number of elements?

测试两个数组是否具有相同数量的元素。这是因为==运算符在两侧都会强制执行标量上下文,并且在标量上下文中,数组被评估为返回其元素数量。

要测试数组是否相等,您需要比较它们的元素,并进行一些附加检查和细化。对于Perl中的许多事情,也有一些模块可以帮助我们完成。

例如,使用Array::Compare,最简单的用法如下:

use Array::Compare;

my $comp = Array::Compare->new;    
...
if ($comp->compare(\@ary1, \@ary2))  # they are equal

这个模块可以设置更多内容,还有一些其他的模块可以用于处理数组和列表等各种工作。

问题中的代码还使用了=(赋值!)而不是比较==

经过简化后:

use warnings;
use strict;
use Data::Dump qw(dd);  # to show complex data structures

use Array::Compare;

my $cobj = Array::Compare->new;

my @data = ( 
   ['CTCTTGCCTCAATCATATAT', 'CTCTTGCCTCATTGATATAT', ... ],
   ['CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', ... ],
   ...
);

my @ary_to_del = ('CACTTGCCTCAATGTAATAT', 'TATCATTGCCCAATTTAAGT', ...);

foreach my $ra (@data) {
    @$ra = () if $cobj->compare(\@ary_to_del, $ra);
}

dd \@data;

这样会“清空”与@ary_to_del相等的匿名数组在@data中,如问题中的代码所示,但是它们的数组引用仍然留在@data中,即使其中没有任何元素。

如果您希望彻底删除这些元素,则可以覆盖该数组。

@data = grep { not $cobj->compare(\@ary_to_del, $_) } @data;

使用grep来过滤输入列表,而不是上面的foreach循环。这样只有代码块评估为true的元素才会在输出列表中返回,并分配给@data


嗨 zdim。谢谢您的回复。我尝试使用 grep 代替 foreach 循环。我遇到了两个问题:1)@ary_to_del 需要解引用,2)它只保留了我想要删除的数组。如何使用它来仅消除我希望删除的数组?foreach 循环确实如您所说的那样工作。 - undefined
@Emma 对的 - (2) 只有那些不相等的才能通过,所以条件需要取反。(1) 方法 compare 需要一个数组的引用,就像第一次使用那样。已修复。对此表示抱歉。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接