Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: setting values in anonymous hash

by quidity (Pilgrim)
on Nov 28, 2000 at 18:17 UTC ( #43671=note: print w/ replies, xml ) Need Help??


in reply to setting values in anonymous hash

You can use map on the expanded hash to alter any undef'ined value to be equal to '' instead. As you cannot use undef as a hash key (it is turned into a string, so becomes '' (although a literal 'undef' becomes the string 'undef')) then this won't hurt any of the keys:

%new_hash = map {defined($_) ? $_ : ''} %{$ref2};

For your example you could replace all the code above with something along the lines of:

$rh_foo = {a=>undef, b=>'b_value', c=>undef, e=>'e_value'}; push @foo, { map {defined($_) ? $_ : ''} %{$rh_foo} }; foreach (keys %{$foo[0]}) { print "$_ => ${$foo[0]}{$_}\n"; }


Comment on Re: setting values in anonymous hash
Select or Download Code
Re: setting values in anonymous hash
by Dominus (Parson) on Nov 28, 2000 at 21:45 UTC
    quidity suggests:
    > %new_hash = map {defined($_) ? $_ : ''} %{$ref2};
    In recent versions of Perl, you can also use a simpler version that modifies the hash in place:
    map { $_ = '' unless defined } %$ref2;
    This is comparable in simplicity to the original code that involved an array instead of a hash.
      map { $_ = '' unless defined } %$ref2;
      To eliminate the void map, and not attack the keys (which don't need attacking), I'd go with:
      defined or $_ = "" for @$ref2{keys %$ref2};
      or for 5.6 and later:
      defined or $_ = "" for values %$ref2;

      -- Randal L. Schwartz, Perl hacker

        Says merlyn:
        > To eliminate the void map ...
        I knew you were going to show up and say this, so please allow me to register my respectful disagreement on the subject of void map. I never understood why you thought it was such a big deal.

        Here's my stupid question for today. I suppose if I really wanted to know, I could load up 5.005. Why doesn't: defined or $_ = "" for values %$ref2;
        Work for versions < 5.6?
      OK, I'm confused. map wants a list, right? So here you're treating the hash as a list, and setting the undefined values to '' as you find them?

      I think that this method would make more sense to me if it went something like

      map { $_ = '' unless defined } values %$ref2;
      I guess I'm just wondering why referring to hashes in a list context is a good idea.

      Update: merlyn rightly points out this is a void usage of map. Perusing the docs for map led me to some insight. We want to test for values that are undefined and change them -- sounds like a job for grep:

      for (grep {not defined} values %$ref2) {$_ = q()};
      fits the bill -- it actually acts on the returned values from grep, so no more void contexts, and actually reads like the task desired.

        Says snax:
        > map wants a list, right?
        Right.
        > So here you're treating the hash as a list, and
        > setting the undefined values to '' as you find them?
        Right. See, you weren't as confused as you thought.
        > I guess I'm just wondering why referring to hashes
        > in a list context is a good idea.
        Uh uh. Innocent until proven guilty. It solves the problem, so the burden of proof is on you to show why it isn't a good idea.

        We use hashes as lists all the time:

        sub stuff { my %hash ; ... return %hash; } %stuff = stuff();
        It isn't a big deal.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://43671]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2014-08-21 05:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (127 votes), past polls