Perl map - need to map an array into a hash as arrayelement->array_index
Solution 1
%hash = map { $arr[$_] => $_ } 0..$#arr;
print Dumper(\%hash)
$VAR1 = {
'Field4' => 4,
'Field2' => 2,
'Field5' => 3,
'Field1' => 1,
'Field3' => 0
};
Solution 2
my %hash;
@hash{@arr} = 0..$#arr;
Solution 3
Here's one more way I can think of to accomplish this:
sub get_bumper {
my $i = 0;
sub { $i++ };
}
my $bump = get_bumper; # $bump is a closure with its very own counter
map { $_ => $bump->(); } @arr;
As with many things that you can do in Perl: Don't do this. :) If the sequence of values you need to assign is more complex (e.g. 0, 1, 4, 9, 16... or a sequence of random numbers, or numbers read from a pipe), it's easy to adapt this approach to it, but it's generally even easier to just use unbeli's approach. The only advantage of this method is that it gives you a nice clean way to provide and consume arbitrary lazy sequences of numbers: a function that needs a caller-specified sequence of numbers can just take a coderef as a parameter, and call it repeatedly to get the numbers.
Solution 4
In Perl 5.12 and later you can use each
on an array to iterate over its index/value pairs:
use 5.012;
my %hash;
while(my ($index, $value) = each @arr) {
$hash{$value} = $index;
}
Gopalakrishnan SA
Updated on June 05, 2022Comments
-
Gopalakrishnan SA about 2 years
I have a array like this:
my @arr = ("Field3","Field1","Field2","Field5","Field4");
Now i use map like below , where /DOSOMETHING/ is the answer am seeking.
my %hash = map {$_ => **/DOSOMETHING/** } @arr
Now I require the hash to look like below:
Field3 => 0 Field1 => 1 Field2 => 2 Field5 => 3 Field4 => 4
Any help?
-
Zaid about 14 yearsIt's a shame
%hash
has to be pre-declared, so we can't write something likemy @hash{@arr} = 0 .. $#arr;
... -
Greg Bacon about 14 years@Zaid There are always cute tricks such as
@$_{@arr} = 0 .. $#arr for \my %hash;
, but eugene's code has less shock value. -
Zaid about 14 years@gbacon : Agreed, one shouldn't sacrifice readability for one-line-cramming. It's just that I would've imagined that Perl could auto-vivify with array slices as well.
-
Greg Bacon about 14 years@Zaid Your proposed syntax would be nice. You should send a patch to p5p!
-
Eugene Yarmash almost 12 yearsWhy not just
my $i; my %hash = map { $_ => $i++ } @arr
-
Ankit Roy almost 12 years@eugeney: Yes, that's much simpler :)