kiransmailid has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl Monks, I am trying to find the number of keys with multiple values in a hash map and delete those keys, as given below.
Kindly help me with this,
Eg., INPUT
'Message1' => [ '0X026003', '0X026004' ],
'Message2' => [ '0X026007' ],
'Message3' => [ '0X026007' ],
'Message4' => [ '0X026005', '0X026006' ]
EXPECTED OUTPUT
'Message2' => [ '0X026007' ],
'Message3' => [ '0X026007' ]
  • Comment on finding the keys with mutliple values in hash and delete them

Replies are listed 'Best First'.
Re: finding the keys with mutliple values in hash and delete them
by hdb (Monsignor) on Mar 19, 2015 at 09:21 UTC

    From all of the keys of your hash, grep those that refer to arrays with length larger than 1, and then delete the corresponding hash slice (all done in one go below):

    use strict; use warnings; use Data::Dumper; my %hash = ( 'Message1' => [ '0X026003', '0X026004' ], 'Message2' => [ '0X026007' ], 'Message3' => [ '0X026007' ], 'Message4' => [ '0X026005', '0X026006' ] ); delete @hash{ grep { @{$hash{$_}} > 1 } keys %hash }; print Dumper \%hash;
      Thank You for the Support :)
Re: finding the keys with mutliple values in hash and delete them
by Discipulus (Canon) on Mar 19, 2015 at 07:57 UTC
    hi kiransmailid and welcome,

    what have you tried and where you encounter problems?
    you have an HashOfArrays as described in perldsc.
    i think you can simply cycle the hash and check for the presence of the element 1 of the array that is the value for that key of the hash.

    L*
    perl -MData::Dumper -e " %h = ('Message2' => [ '0X026007' ], 'Message +4' => [ '0X026005', '0X026006' ] ); foreach $k(keys %h) { delete $h{$k} if defined $h{$k}[1] } print Dumper(\%h) " $VAR1 = { 'Message2' => [ '0X026007' ] };
    UPDATE: in the remote past existed caveats about modifying hashes while iterating over them; we are speaking of Perl release prior 5.8 see Adding or removing keys while iterating over a hash Re: Deleting Hash Entries while Iterating

    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Minor nitpick: I'd use exists rather than defined, in the (probably very unlikely) event of something like

      'Message5' => [ '0X026008', undef, '0X026009' ]
      WOW !!!
      Thanks a Lot, that works :)