2010-11-01 39 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:那就是他已經在做:製作包含要被刪除原始列表項第二個列表,然後遍歷副本。 – 2010-11-01 07:12:34

1

你可以使用這樣的哈希方法,

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

使用散列比查詢數組更有效,但是您的'if ... delete'不會執行與其原始代碼類似的任何操作。 – cjm 2010-11-01 08:38:08

2

你得到什麼樣的「怪異的結果」?您發佈的代碼中沒有任何明顯的問題(你不改變@associationsToRemove在遍歷它,所以不適用「不從你迭代一個列表中刪除」),所以我傾向於懷疑實際問題在agentConf->RemoveAssociation