Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

map it back jack

by jettero (Monsignor)
on Dec 16, 2000 at 02:41 UTC ( [id://46953]=perlquestion: print w/replies, xml ) Need Help??

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

I just know this is possible... but I wouldn't know where to begin. I wanna map my array back to a hash like so:
foreach(@elements) { $v = $_; $v =~ s/_/ /g; $myhash{$_} = $v; }

The catch is that I wanna do it with map() on a tiny little line. :) Is there a way to build a hash with map?

Replies are listed 'Best First'.
Re: map it back jack
by I0 (Priest) on Dec 16, 2000 at 02:46 UTC
    %myhash = map{ $v = $_; $v =~ s/_/ /g; $_,$v } @elements;
      Seems like you can save a couple of keystrokes if you're not particular about what ends up in $v, since s/// operates on $_:

      my $v; my %myhash = map { $v = $_; s/_/ /g; $v, $_ } @elements;
      Is there a way to pare it down more? (The Monastery needs a golf course!)

      Update: As I0 points out, this also modifies @elements, which may not be what you want.

      johannz's for construct is looking the most elegant to me now.

        In the quest for Shorter and More Efficient:
        my %myhash = map { $v=$_; y/_/ /; $_,$v } @elements;
        You may not be particular about what ends up in $v, but if you're particular about what ends up in @elements you won't want to modify $_ ($v=$_)=~tr/_/ /;$_,$v
Re: map it back jack
by johannz (Hermit) on Dec 16, 2000 at 03:04 UTC

    I can do it in just one line, but I prefer using just a reverse for statement:

    my %myHash; ($myHash{$_} = $_) =~ s/_/ /g for (@elements);
      Of the solutions, I like this one the best. I would avoid the map function unless you are certain there is nothing in %myHash that you want to keep. None of the map solutions shown preserve any original elements the hash might contain-- except maybe the one with the void context problem. :)
Re: map it back jack
by Hot Pastrami (Monk) on Dec 16, 2000 at 02:47 UTC
    It's quite possible, but probably not as neat and readable as the foreach() loop:
    my %myhash; my $v; map { $v = $_; $v =~ s/_/ /g; $myhash{$_}=$v; } @elements;
    Update: Hmm, why did I get dinged negative votes for this one? Is it considered bad to make the hash assignment in the map block?

    Hot Pastrami
      Many people frown on using map and grep in a void context. Both commands are intended for building a list that is returned at the end; if you don't need the returned list from map or grep, it's cleaner to use foreach instead.
      my %myhash; foreach (@elements) { my $v = $_; $v =~ tr/_/ /; $myhash{$_} = $v; }
      UPDATE: runrig pointed out that the my $v can be moved inside the loop, which didn't occur to me as I was rewriting the map to a foreach. I've made that change now.
        Alrighty, thanks for the tip.

        Hot Pastrami
Re: map it back jack
by turnstep (Parson) on Dec 16, 2000 at 04:19 UTC
    Here's a way to do it without using for or map:
    $myhash{$v}=$_ while defined ($v=$_=pop@elements and y/_/ /);
      Watch out if @elements actually contains an undef value... :)

      This even more than the rest has the problem of modifying the @elements array. In this case, it empties it.

        Why is it a problem? The original question never asks that the array remained untouched, merely (implied) that "for[each]" should not be used. Why not remove each element as we put it in the hash? :) TMTOWTDI
Re: map it back jack
by johannz (Hermit) on Dec 16, 2000 at 05:01 UTC

    If we accept that the original array is going to be modified:

    @myHash{@elements} = map {y/_/ /; $_} @elements;

    Update:
    Oops, this doesn't quite work. Helps when you test something to actually look at the results. This does the map, and therefor the modification to @elements, before performing the LHS.

      This works however. And it doesn't change @elements

      @myHash{@elements} = map {join ' ', split '_'} @elements;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://46953]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2024-04-24 09:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found