我有两个数组,
my @test = ('a','b','c','d','e',f,'g','h');
my @test2 = ('h','b','d');
我正在尝试遍历数组@test
,并将元素与@test2,
中的元素相匹配,删除那些不存在的元素。
我有以下代码:
foreach my $header (@test) {
if( exists $test2[$header]){
# do nothing
}
else {
delete $test[$header];
}
}
所以,我希望数组@test看起来像这样(忽略这个可以按字母顺序排序的事实):
my @test = ('b','d','h');
然而,目前我的阵列在foreach循环后保持不变,有人可以建议为什么吗?
答案 0 :(得分:2)
你误解了'标题'设置的内容。它被设置为数组中的值的别名(别名)。
所以
foreach my $header (@test) {
print $header,"\n";
}
会给您a
,b
,c
等
但是,您尝试访问无效的$test2['a']
,因为它应该是数字。
实际上,这是一个很好的案例研究,说明为什么你应该使用strict
和warnings
,因为这会告诉你这个问题:
Argument "a" isn't numeric in array or hash lookup at
Argument "b" isn't numeric in array or hash lookup at
等
所以它不是实际做任何事情。
您不应该以这种方式使用delete,因为您在迭代时从列表中删除。这并不好,即使没有使用字母作为数组索引是无意义的。
你可以这样做而不是:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my @test = ('a','b','c','d','e','f','g','h');
my @test2 = ('h','b','d');
my %is_in_test2 = map { $_ => 1 } @test2;
@test = grep { $is_in_test2{$_} } @test;
print Dumper \@test;
如果你想按索引进行迭代,你可以这样做:
for my $index ( 0..$#test ) {
print "$index => $test[$index]\n";
}
但是我仍然建议在迭代时删除并不是一个很好的计划,因为修改一个你正在迭代它的东西(并且旨在调整数组的大小)是一个很好的方法来结束奇怪的错误。
所以尽管你可以:
for my $index ( 0..$#test ) {
print "$index => $test[$index]\n";
delete $test[$index] if not $is_in_test2{$test[$index]};
}
print Dumper \@test;
你最终得到的是:
$VAR1 = [
undef,
'b',
undef,
'd',
undef,
undef,
undef,
'h'
];
对于更一般的情况,有一个FAQ: How do I computer the difference/intersection of two arrays
答案 1 :(得分:0)
use strict;
use warnings;
my @test = ('a','b','c','d','e','f','g','h');
my @test2 = ('h','b','d');
foreach my $header (@test) {
foreach my $header2 (@test2) {
if( $header eq $header2) {
print "$header,"; #prints only existing values
}
else {
#doNothing
}
}
}
注意:当您处理包含大量元素的数组时,此方法不可行。