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

Dear Monks,

I'd like to remove key/value pairs from a hash whose values are references.
my %h = ( one => 'v1', two => 'v2', three => { a => 'x', c => 'y' } ); my %norefs = map { $_ => $h{$_} unless ref $h{$_} } keys %h;

This doesn't work because when ref... evaluates as TRUE, it is also pushed onto the hash (and used as a hash key). Can this be done with map, or is it better to just my %norefs = %h; grep { ref $norefs{$_} && delete $norefs{$_} } keys %norefs;?

-- telcontar

Replies are listed 'Best First'.
Re: Removing key/value pairs from a hash
by oha (Friar) on Nov 27, 2007 at 11:39 UTC
    the most similar working way i found is:
    my %norefs = map { ref $h{$_} ? () : ($_,$h{$_}) } keys %h;
    Oha
Re: Removing key/value pairs from a hash
by mickeyn (Priest) on Nov 27, 2007 at 12:13 UTC
    delete $h{$_} for (grep {ref $h{$_}} keys %h);
    ;-)
    Mickey
Re: Removing key/value pairs from a hash
by johngg (Canon) on Nov 27, 2007 at 11:39 UTC
    Not tested but try this.

    my %norefs = map { $_ => $h{ $_ } } grep { ! ref $h{ $_ } } keys %h;

    I hope this works for you.

    Cheers,

    JohnGG

Re: Removing key/value pairs from a hash
by sh1tn (Priest) on Nov 27, 2007 at 13:22 UTC
    a little shorter:

    delete @h{grep(ref($h{$_}), keys(%h))};


Re: Removing key/value pairs from a hash
by jdporter (Paladin) on Nov 27, 2007 at 15:08 UTC

    Another way:

    my @keepers = grep !ref($h{$_}), keys %h; my %norefs; @norefs{@keepers} = @h{@keepers};
    A word spoken in Mind will reach its own level, in the objective world, by its own weight