1

I would like to use Perl to delete keys from a hash map that match values in a given array.

Example:

Input:

   @array = ("apple", "banana" , "cherry")
   %hash = ( '/abc/apple/somestring' => val1,
             '/banana/somestring/somesting' => val2,
             '/xyz/apple/somestring'   => val3,
             '/somestring/somestring/'        => val4,
             '/xyz/somestring/random'        => val2,
           )

Output:

   %hash = ( '/somestring/somestring/'        => val4,
             '/xyz/somesting/random'        => val2,
           )

1 Answer 1

4

Simple:

  1. For each element in the array, select the matching hash keys

    for my $elem (@array) {
      my @matching_keys = grep { 0 <= index $_, $elem } keys %hash;
    
  2. Then, delete the hash entries with the matching keys:

      delete @hash{@matching_keys};
    }
    

The 0 <= index $_, $elem could also be written as /\Q$elem/, if you are optimising for readability instead of speed.


Alternatively: build a regex that matches all elems in the array:

my $rx = join '|', map quotemeta, @array;

Then, select and delete all keys that match this regex:

my @matching_keys = grep /$rx/, keys %hash;
delete @hash{@matching_keys};

This should be more efficient.

Sign up to request clarification or add additional context in comments.

2 Comments

That works like a charm. I was iterating using foreach loop and it didn't work.
@amon, bravo! the best tip that I've read today :) delete + slices! bravo!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.