giordano
giordano

Reputation: 3152

Perl: Delete element in hash based on their values

I have a hash and want to delete some elements (element = key+value). It is easy to delete an element by key but I don't know how to do if the condition to delete is based on the value.

my %h = (  'a' => 1
         , 'b' => 1
         , 'c' => 2
       );

# delete by key
delete $h{'c'};

print map { "$_ $h{$_}\n" } keys %h;
# a 1
# b 1

I would like to delete using the value:

delete %h value >1

Upvotes: 1

Views: 541

Answers (1)

Shawn
Shawn

Reputation: 52336

You can efficiently loop over the entries with each and delete matching ones:

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my %h = (
    'a' => 1,
    'b' => 1,
    'c' => 2
    );

while (my ($k, $v) = each %h) {
    delete $h{$k} if $v > 1;
}

print Dumper(\%h);

From the each documentation (Emphasis added):

Any insertion into the hash may change the order, as will any deletion, with the exception that the most recent key returned by each or keys may be deleted without changing the order.

This means that the above loop can safely look at every element of the hash and delete all of those that meet the criteria.


You can also use a slice to delete multiple entries at once. Just have to build a list of the keys to remove, for example by filtering the result of keys:

delete @h{grep { $h{$_} > 1 } keys %h};

Upvotes: 5

Related Questions