0

Consider the following nested loops:

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

Now, I take a sample case where three values (A,B,C) will be compared against two values (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.

In this case, C should be compared first with B, being first value, but this comparison is skipped, and it only scans from the next element after the one that was found equal. If I remove last termination condition and let the loop run for total number of scans, then it works all fine, but I need to find out why in this case, $key refers to the next compared value and not to the first value once loop is restarted after getting terminated with last keyword.

Any help will be appreciated.

Manoj Agarwal
  • 365
  • 2
  • 17

2 Answers2

4

Use

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

See keys.

But, why are you iterating over the hash? Why don't you just

if (exists $deleted_documents_names{$document_name}) {
choroba
  • 231,213
  • 25
  • 204
  • 289
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).