Re: map it back jack
by I0 (Priest) on Dec 16, 2000 at 02:46 UTC
|
%myhash = map{ $v = $_; $v =~ s/_/ /g; $_,$v } @elements; | [reply] |
|
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.
| [reply] [d/l] |
|
In the quest for Shorter and More Efficient:
my %myhash = map { $v=$_; y/_/ /; $_,$v } @elements;
| [reply] [d/l] |
|
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
| [reply] [d/l] |
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);
| [reply] [d/l] |
|
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. :)
| [reply] |
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 | [reply] [d/l] |
|
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. | [reply] [d/l] |
|
Alrighty, thanks for the tip.
Hot Pastrami
| [reply] |
|
| [reply] |
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/_/ /);
| [reply] [d/l] |
|
Watch out if @elements actually contains an undef value... :)
| [reply] |
|
| [reply] |
|
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
| [reply] |
Re: map it back jack
by johannz (Hermit) on Dec 16, 2000 at 05:01 UTC
|
@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.
| [reply] [d/l] |
|
@myHash{@elements} = map {join ' ', split '_'} @elements;
| [reply] [d/l] |