我从这个perl代码中得到了一些奇怪的结果 - 我需要从Association对象列表中删除几个元素。
我的方法是扫描列表一次,将匹配推送到另一个数组,然后迭代该数组并删除每个数组,但我没有逃脱“迭代陷阱时不要删除”。
有关如何避免这种情况的任何想法?非常感谢。
my @agentConfAssociationDeletionsList = (
"AcceptTPCookie",
"AgentNamesAreFQHostNames",
"BadCssChars",
"LogLocalTime"
);
#find associations to remove
my @associationsToRemove = ();
foreach my $association ($agentConf->GetAssociations()) {
if ( grep {$_ eq $association->Name()} @agentConfAssociationDeletionsList) {
print "pushing " . $association->Name() . "\n";
push(@associationsToRemove, $association);
}
}
#remove them
foreach my $association (@associationsToRemove) {
print "removing association: " . $association->Name();
agentConf->RemoveAssociation($association);
}
答案 0 :(得分:3)
你的第一个循环是:
my @associationsToRemove = ();
foreach my $association ($agentConf->GetAssociations()) {
if ( grep {$_ eq $association->Name()} @agentConfAssociationDeletionsList) {
print "pushing " . $association->Name() . "\n";
push(@associationsToRemove, $association);
}
}
相当于:
my @associationsToRemove = ();
my @associations = $agentConf->GetAssociations();
foreach my $association (@associations) {
if ( grep {$_ eq $association->Name()} @agentConfAssociationDeletionsList) {
print "pushing " . $association->Name() . "\n";
push(@associationsToRemove, $association);
}
}
因此,在第一次迭代之前调用GetAssociations()
环。这里没有“在迭代陷阱时不删除”
陷阱通常出现在基于each
的循环内部和C风格for
循环。问题可能在RemoveAssocition()
内部
方法
另一种可能性是从$association
对象返回
当GetAssociations()
被传回时,$association
没有被完全复制
$agentConf
个对象仍然可以是$agentConf
的内部数据。这可能是一个隐藏的“不要在迭代时删除”的陷阱,很难说不知道agentConf
的实现甚至是它的接口是什么。
另外,你在第二个循环中错过{{1}}上的印记但是 这可能只是一个错字。
答案 1 :(得分:2)
你得到什么样的“奇怪结果”?你发布的代码没有明显的问题(你在迭代它时没有改变@associationsToRemove
,所以“不要从你正在迭代的列表中删除”不适用),所以我'我倾向于怀疑实际问题在agentConf->RemoveAssociation
。
答案 2 :(得分:1)
你可以使用像这样的哈希方法,
my %h = map {$_ => 1 } @agentConfAssociationDeletionsList;
if (exists $h{$agentConfAssociationDeletionsList}) {
delete $h{$agentConfAssociationDeletionsList}; # like that
}
答案 3 :(得分:0)
制作原始列表的副本,并在删除时迭代副本。