简体   繁体   中英

Unable to Access Element in a Perl Hash

I have a hash, populated with following test data:

my %non_root_files = ('views/SPYGLASS_HOME/bin/sample_sgdc_file_contents_1.sgdc' => 1, 
                  'views/SPYGLASS_HOME/bin/sample_sgdc_file_contents.sgdc' => 1,
                  'views/SPYGLASS_HOME/bin/test_2.sgdc' => 1,
                  'views/SPYGLASS_HOME/bin/test_4.sgdc' => 1,
                  'views/SPYGLASS_HOME/bin/test_5.sgdc' => 1,
                  'views/SPYGLASS_HOME/bin/test_6.sgdc' => 1);

In another array, I have the following data:

my @files = ('views/SPYGLASS_HOME/bin/sample_sgdc_file_contents.sgdc', 
             'views/SPYGLASS_HOME/bin/test_2.sgdc',
             'views/SPYGLASS_HOME/bin/sample_sgdc_file_contents_1.sgdc',
             'views/SPYGLASS_HOME/bin/test_5.sgdc',
             'views/SPYGLASS_HOME/bin/test_7.sgdc',
             'views/SPYGLASS_HOME/bin/sample_sgdc_file_contents_2.sgdc');

what I need to do is to check if each entry in the array is present in the hash, and delete from the original array, so I do it as follows:

sub deleteDuplicate{

    $originalList_ref = shift;
    my $index = 0;
    foreach my $element (@{$originalList_ref})
    {
       if(exists $non_root_files{$element})
       {
          splice(@{$originalList_ref}, $index, 1);
       }
       $index++;
    }
}

However, for some entries which are actually present in the hash, the lookup with exists is failing. The element is there in the hash, but if condition is returning false. Can anyone please explain the reason for this and how to correct it?

Thanks!

Brian's comment is correct; you want:

   if(exists $non_root_files{$element})
   {
      splice(@{$originalList_ref}, $index, 1);
   }
   else
   {
      $index++;
   }

(If you delete an entry in the array, the next entry will move back to that same index).

Regarding foreach loops in perldoc perlsyn :

If any part of LIST is an array, foreach will get very confused if you add or remove elements within the loop body, for example with splice. So don't do that.

There's a much easier way to do this:

sub deleteDuplicate {
    $original_ref = shift;
    $originalList_ref = [ grep { ! exists $non_root_files{$_} } @$originalList_ref ];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM