首先,$a =~ /$b/
不检查是否相等。你需要
$second_hash_array[$j]{geneID} =~ m/^\Q$first_hash_array[$i]{geneID}\E\z/
或者干脆
$second_hash_array[$j]{geneID} eq $first_hash_array[$i]{geneID}
为了那个原因。
第二,
for my $i (0 .. $#first_hash_array) {
... $first_hash_array[$i] ...
}
可以更简洁地写成
for my $first (@first_hash_array) {
... $first ...
}
名单上的下一个是
for my $second (@second_hash_array) {
if (...) {
push @subset, $second;
}
}
可以$second
多次添加@subset
。您要么需要添加一个last
# Perform the push if the condition is true for any element.
for my $second (@second_hash_array) {
if (...) {
push @subset, $second;
last;
}
}
或移出push
循环
# Perform the push if the condition is true for all elements.
my $flag = 1;
for my $second (@second_hash_array) {
if (!...) {
$flag = 0;
last;
}
}
if ($flag) {
push @subset, $second;
}
取决于你想做什么。
要从数组中删除,可以使用splice
. 但是从数组中删除会弄乱所有索引,因此最好向后迭代数组(从最后一个索引到第一个索引)。
它不仅复杂,而且价格昂贵。每次拼接时,数组中的所有后续元素都需要移动。
更好的方法是过滤元素并将结果元素分配给数组。
my @new_first_hash_array;
for my $first (@first_hash_array) {
my $found = 0;
for my $second (@second_hash_array) {
if ($first->{geneID} eq $second->{geneID}) {
$found = 1;
last;
}
}
if ($found) {
push @new_first_hash_array, $first;
}
}
@first_hash_array = @new_first_hash_array;
反复迭代@second_hash_array
是不必要的昂贵。
my %geneIDs_to_keep;
for (@second_hash_array) {
++$geneIDs_to_keep{ $_->{geneID} };
}
my @new_first_hash_array;
for (@first_hash_array) {
if ($geneIDs_to_keep{ $_->{geneID} }) {
push @new_first_hash_array, $_;
}
}
@first_hash_array = @new_first_hash_array;
最后,我们可以将其替换for
为 agrep
以给出以下简单有效的答案:
my %geneIDs_to_keep;
++$geneIDs_to_keep{ $_->{geneID} } for @second_hash_array;
@first_hash_array = grep $geneIDs_to_keep{ $_->{geneID} }, @first_hash_array;