Perl map - 需要将数组映射成哈希表,键为数组元素,值为数组索引

16

我有一个这样的数组:

my @arr = ("Field3","Field1","Field2","Field5","Field4");

我现在使用下面的 map ,其中 /DOSOMETHING/ 就是我正在寻找的答案。

my %hash = map {$_ => **/DOSOMETHING/** } @arr

现在我需要哈希表的格式如下:

Field3 => 0
Field1 => 1
Field2 => 2
Field5 => 3
Field4 => 4

有人可以帮忙吗?

5个回答

26
%hash = map { $arr[$_] => $_ } 0..$#arr;

print Dumper(\%hash)
$VAR1 = {
          'Field4' => 4,
          'Field2' => 2,
          'Field5' => 3,
          'Field1' => 1,
          'Field3' => 0
        };

19
my %hash;
@hash{@arr} = 0..$#arr;

3
"%hash" 需要预先声明,这让我们无法编写类似于 "my @hash{@arr} = ​​0 .. $#arr;" 的代码,真是遗憾。 - Zaid
4
@Zaid 通常有一些可爱的技巧,例如 @$_{@arr} = 0 .. $#arr for \my %hash;,但是 Eugene 的代码更加简洁明了。 - Greg Bacon
@gbacon:同意,我们不应该为了一行代码而牺牲可读性。只是我本来以为Perl也可以自动创建数组切片。 - Zaid
@Zaid,你提出的语法很好。你应该向p5p发送一个补丁! - Greg Bacon

2
这是我能想到的另一种完成此任务的方法:
sub get_bumper {
    my $i = 0;
    sub { $i++ };
}

my $bump = get_bumper;         # $bump is a closure with its very own counter
map { $_ => $bump->(); } @arr;

与 Perl 中许多你可以做的事情一样:不要这样做。 :) 如果你需要分配的值序列更加复杂(例如 0、1、4、9、16... 或者从管道读取的随机数序列),那么很容易将此方法调整适用于它,但通常更容易使用 unbeli's approach。此方法的唯一优点是它提供了一个漂亮干净的方式来提供和消耗任意惰性数字序列:需要调用方指定数字序列的函数只需将一个 coderef 作为参数传递,并重复调用它以获取数字。

3
为什么不直接使用 my $i; my %hash = map { $_ => $i++ } @arr - Eugene Yarmash
@eugeney:是的,那样简单多了 :) - j_random_hacker

2
在 Perl 5.12 及更高版本中,您可以对数组使用 each 来迭代其索引/值对:
use 5.012;

my %hash;

while(my ($index, $value) = each @arr) {
    $hash{$value} = $index;
}

1

这是一个非常老的问题,但我遇到了同样的问题,这是我的解决方案:

use feature ':5.10';

my @arr = ("Field3","Field1","Field2","Field5","Field4");
my %hash = map {state $i = 0; $_ => $i++} @arr;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接