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

Hi everyone. I've got a simple question about hashes. I've got a hash called %hash and an array called @mips. I want to essentially replace the keys of %hash with the elements of @mips--most of them are the same as the keys, so of course I want to preserve those values. If there is no corresponding value in the hash for the key in mips, I want it to make a value of 999. So, just to make this clear with an example:
my @mips = qw( A B C D E F) my %hash = ( A => 1.6543 B => 2.45433 C => -.4533 E => 1.453 G => -1.875 ); I want a resulting hash that looks like: A => 1.6543 B => 2.45433 C => -.4533 D => 999 E => 1.453 F => 999 Any suggestions are appreciated! thanks,Evan

Replies are listed 'Best First'.
Re: Simple Hash problem
by Juerd (Abbot) on Feb 08, 2002 at 20:45 UTC
    You forgot a bunch of commas.

    Golfing:
    $new{$_}=defined$old{$_}?$old{$_}:999 for@mips
    If there are no 0 values:
    $new{$_}=$old{$_}||999 for@mips
    The first, but perl6 (I think):
    $new{$_}=$old{$_}//999 for@mips

    The first one written in a more readable way:
    for (@mips) { $new{$_} = defined($old{$_}) ? $old{$_} : 999; }


    Another approach:
    %new=map{($_,defined$old{$_}?$old{$_}:999}@mips
    If 0 may be 999:
    %new=map{($_,$old{$_}||999)}@mips
    Another perl6 try:
    %new=map{($_,$old{$_}//999)}@mips

    Again, the first of this approach written in a readable manner:
    %new = map { ($_ => defined($old{$_}) ? $old{$_} : 999) } @mips;



    Good luck.

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

Re: Simple Hash problem
by VSarkiss (Monsignor) on Feb 08, 2002 at 20:16 UTC

    The simplest way is with a single loop:

    foreach my $k (@mips) { $hash{$k} = 999 unless exists $hash{$k}; }
    This might even touch off a round of golf...

    HTH

      It is simple, but it doesn't quite match the sample results. This approach ignores elements in %hash that are not in @mips, whereas the original example removed them.

      Here's a small rework that fixes it:
      my %newhash = (); for (@mips) { $newhash{$_} = $hash{$_} || 999; } %hash = %newhash;

      lestrrat's solution is much more fun to look at, though.

      Vavoom
        I am not following why you needed to create the temp hash. My output appears to be correct for the example given with the following line of code.

        for(@mips){$hash{$_}||=999}

        UPDATE:
        Thanks crazyinsomniac, after reading these posts several times and talking with you in CB I realize that the example above did not have G in it once it was processed. I read the question and did not examine the output. In the text of the original question it does not state that missing keys should be removed, it merely states that the values should be 999 if they have none.
      okay, i'll bite... (41 chars--surely it can be done in less?)

      map{exists$hash{$_}or$hash{$_}=999}@mips

      update: (39 chars)

      exists$hash{$_}or$hash{$_}=999for@mips
      update2: vavoom is right. back to the drawing board... (75 chars--results in %h, and it's a little obfuscated)

      @$_{@mips}=(999)x@mips for\my%h;exists$hash{$_}and$h{$_}=$hash{$_}for@ +mips;

      ~Particle

Re: Simple Hash problem
by lestrrat (Deacon) on Feb 08, 2002 at 20:19 UTC

    Will this work?

    my %hash = { ... original data ... }; my %tmp = map{ ( $_, exists $hash{ $_ } ? $hash{ $_ } : 999 ) } @mi +ps;
Re: Simple Hash problem
by Zaxo (Archbishop) on Feb 08, 2002 at 20:48 UTC

    39 is probably not golf standard, but one character names would make it 30:

    exists$hash{$_}or$hash{$_}=999for@mips; 123456789012345678901234567890123456789

    After Compline,
    Zaxo

Re: Simple Hash problem
by impossiblerobot (Deacon) on Feb 08, 2002 at 20:53 UTC
    I did it with a hash slice. Probably not very memory efficient:
    @hash{ grep( !defined($hash{$_}), @mips) } = (999) x @mips;
    Update: Better hash slice solution:
    @new{@mips}=map(($hash{$_}||999),@mips);
    I had also missed the requirement to eliminate key/values not in @mips. ++Vavoom.

    Impossible Robot