2010-11-01 2 views
0

У меня есть некоторые странные результаты из этого кода Perl. Мне нужно удалить несколько элементов из списка объектов Ассоциации.Безопасный способ удаления элементов из списка на Perl?

Мой подход заключается в том, чтобы отсканировать список один раз, нажать совпадения на другой массив, затем перебрать этот массив и удалить каждый из них, но я не избежал «не удалять, итерации».

Любые идеи о том, как этого избежать? Большое спасибо.

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); 
} 

ответ

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 во втором цикле, но это, вероятно, только опечатка.

0

Сделайте копию первоначального списка и повторите попытку копирования при удалении.

+0

-1: Это то, что он уже делает: создание второго списка, содержащего элементы исходного списка, которые должны быть удалены, а затем итерации по копии. –

1

вы можете использовать хэш-подход, как это,

my %h = map {$_ => 1 } @agentConfAssociationDeletionsList; 
if (exists $h{$agentConfAssociationDeletionsList}) { 
    delete $h{$agentConfAssociationDeletionsList}; # like that 
} 
+0

Использование хэша более эффективно, чем grepping массива, но ваш 'if ... delete' не делает ничего похожего на его исходный код. – cjm

2

Какого рода «странные результаты» вы получаете? Код, который вы опубликовали, не имеет в нем очевидных проблем (вы не меняете @associationsToRemove, итерации по нему, поэтому «не удалять из списка, который вы повторяете» не применяется), поэтому я склонен подозревать что фактическая проблема находится в agentConf->RemoveAssociation.

Смежные вопросы