in reply to from array to hash with grep

"You can't make shit up and expect Perl to know what it means, retardo!"... ((in)famous MJD quote)

There must be a logical technical reason to how it should/could work. grep reads a list and checks for which ones the condition evaluates to true. That's all. That doesn't look very useful.

Now you're try this with map, it'll build a list of return values instead. Now what would the value returned from the regexp be? Why, you have capturing parens, map calls the regexp in list context, so it'll return an empty list for no match, and a list of captured values for matches. So

@result = map /\w{3}_(\w)/, @inp;
will put ('A', 'B', 'C') into the array, for your particular input.

If you foreach through that list, you can use each as a hash key, in turn. So this will do what you want:

$inp{$_} = 1 foreach map /\w{3}_(\w)/, @inp;

It looks close to what you made up, but it isn't. Not really.

Replies are listed 'Best First'.
Re^2: from array to hash with grep
by jeanluca (Deacon) on Jun 15, 2006 at 08:18 UTC
    OK, al that makes me understand map and grep better. I just realized that I want it a little bit different, I need a hash with the same keys but the values should be the whole string, so you would get:
    $inp{A} = 'abc_A_bla' ; etc
    Is this still possible with map or should I switch to a simpel foreach
    foreach ( @inp ) { ($key) = $_ =~ /\w{3}_(\w)/ ; $inp{$key} = $_ ; }
    ?

    Luca
      It's still possible but you'll have to use something closer to what sonofason wrote. For each match, you need to create a ($key, $value) pair so the list constructed by map is more like ($key1, $value1, $key2, $value2, $key2, $value3) for the three values. That way, assigning to the hash will insert them as you want.

      Now the code you can use to do that, can read for example:

      @flat = map { /\w{3}_(\w)/ ? ($1, $_) : () } @inp;
      It'll create a pair like ("A", "abc_A_bla") for a match, and an empty list for no match.

      Assign to the hash, and you get:

      %inp = map { /\w{3}_(\w)/ ? ($1, $_) : () } @inp;
      my @inp = ("abc_A_bla", "abc_B_bla", "abc_C_bla"); my %inp = map { /\w{3}_(\w)/; $1 => $_ } @inp ; foreach ( keys %inp ) { print "$_ => $inp{$_}\n"; }

      Update: Better to use bart's version which includes checks for when the regex doesn't match.

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg