0

考虑以下嵌套循环:

my %deleted_documents_names = map { $_ => 1 }
                $self->{MANUAL}->get_deleted_documents();

while($sth->fetch){
  .....
  .....
  .....
  while(my ($key, $value) = each(%deleted_documents_names)){
        {
         if($document_name eq $key){
              $del_status=1;
              last;
         }
        }
  if($del_status==1){next;} 
  .....
  .....
  .....
  .....
}

现在,我举一个示例,其中三个值(A,B,C)将与两个值(B,C)进行比较。

First scan:
A compared to B
A compared to C

Second scan:
B compared to B 
Loop is terminated.

Third scan:
C is compared with C.

在这种情况下,应首先将 C 与 B 进行比较,作为第一个值,但此比较被跳过,它仅从发现相等的元素之后的下一个元素开始扫描。如果我删除最后一个终止条件并让循环运行总扫描次数,那么它工作得很好,但我需要找出为什么在这种情况下,$key 指的是下一个比较值而不是第一个值一次循环在使用 last 关键字终止后重新启动。

任何帮助将不胜感激。

4

2 回答 2

4

采用

keys %deleted_documents_names ; # Reset the "each" iterator.

但是,你为什么要遍历哈希?你为什么不只是

if (exists $deleted_documents_names{$document_name}) {
于 2013-02-21T10:51:05.357 回答
4

each() is a function that returns key-value pairs from a hash until it reaches the end. It is not aware of the scope it was called in, and doesn't know anything about your while loop logic. See the documentation here.

It can be reset by calling keys %hash or values %hash.

Update: however, as Choroba points out, you don't really need this loop. Your loop and accompanying logic could be replaced by this:

next if (exists $deleted_documents_names{$document_name});

(Hashes are designed with a structure that allows a key to be quickly found. In fact, this structure is what gives them the name "hashes". So doing it this way will be much more efficient than looping through all elements and testing each one).

于 2013-02-21T10:53:41.093 回答