in reply to Re: map and grep (but for hashes)
in thread map and grep (but for hashes)

It would depend on what you are trying to do, probably. The one thing I've noticed is that usually I don't actually need a new hash: I just need to know which values are in the new hash.

My other trick would be to split it into two lines, and use a hash slice:

@new_keys = grep { $hash{$_} == $condition } keys %hash; @new_hash{@new_keys} = @hash{@new_keys};

I'm sure there are other ways, but that's fairly short and clear.

(Fixed: Thanks lostjimmy.)

Replies are listed 'Best First'.
Re^3: map and grep (but for hashes)
by lostjimmy (Chaplain) on Jan 30, 2009 at 19:48 UTC

    I agree, I do find that I almost always need just the keys. I think I just always end up thinking too much about so I come up with something convoluted. It's like my brain turns off when it comes to map and hashes.

    BTW, that should be @new_keys = grep, not map

      OK, wait, you are not Captain Kirk, this is not the Kobayashi Maru, and you do not get to change the conditions of the test to save the ship and defeat the Klingons. Always reducing things to arrays...it's like blending things that shouldn't be blended.

      It's actually extremely beneficial to be able to have operations that give you hashes back.

      It seems like there's no terse ways to do this in an expression, and it would be better to do it in a little routine.

      That's mostly how I've been operating, but I don't like always breaking things down into lists. It's good for algorithms, but you tend to lose structure.

      The hmap and hgrep methods seem like a nice way to do that, because when I'm putting things together, it seems like they want to go into a big anonymous structure (multi-level hash). Think of assembling JSON like things for example. In these cases I find it more natural to work with hashes, and hashes of hashes and so forth.

      By the answers it seems like the shortest thing is a few lines, which is not overly long, but lacks the super terseness of map or grep. So I think that means I need to write a little function. This isn't so hard, but it does seem that map and grep are so versatile, I was wondering if there were aspects of them I was "not getting", and therefore if there were some ultra-compact expression. It seems like 3 lines is about as short as you can go.

      Thanks, Roger
Re^3: map and grep (but for hashes)
by zerohero (Monk) on Jan 30, 2009 at 20:17 UTC
    >> @new_keys = grep { $hash{$_} == $condition } keys %hash; >> @new_hash{@new_keys} = @hash{@new_keys};

    OK, sorry I missed this second line. This is how you put everything together. Fairly terse. I'd imagine map is a little less terse.

    So I think this argues for a little function. I just wanted to make sure that there wasn't any really terse form that eliminated the need for a function.

      Oh, there probably is. I could one-line the above with not much work if I really wanted to. It would just be ugly.

      Hmm, thinking about map... I'm not completely sure this would work, but I think it would: (I'm assuming you want to modify the values.)

      @new_hash{keys %hash} = map { mod_func($hash{$_}) } keys %hash;

      (This assumes the two invocations of 'keys' will be stable, which I'm not sure you can rely on.)