3

我有这个:

%lookup = (
    'Shelf' => { storage_types => 'Flat, Default' },
    'Locker' => { storage_types => 'Valuable' },
);

我想得到这个:

%reverse_lookup = (
    'Flat' => 'Shelf',
    'Default' => 'Shelf',
    'Valuable' => 'Locker',
);

例如,我可以在测试中循环浏览存储类型,并检查子例程是否返回正确的位置。

我无法理解多个列表扩展部分。

%reverse_lookup = map { split(/,\s*/, $lookup{$_}) => $_ } keys %lookup; # wrong

我想用 map 或类似的东西简洁地完成这一切,而不是 foreach 循环。

4

5 回答 5

5

您不能使用单个映射来做到这一点,因为它遍历 %lookup 哈希的元素,而不是遍历内部的列表。因此,在这种情况下,您将在输出散列中拥有与源散列中相同数量的键。

但是您可以使用嵌套映射 - 首先将迭代主要哈希元素,其次将迭代内部列表。

my %lookup = (
    'Shelf' => { storage_types => 'Flat, Default' },
    'Locker' => { storage_types => 'Valuable' },
);
my %reverse_lookup = map { my $key_name = $_; map {$_ => $key_name} (split(/,\s*/, $lookup{$_}->{storage_types})) } keys %lookup;

use Data::Dumper; print Dumper \%reverse_lookup;  

PS foreach有什么问题?:)

于 2012-08-10T13:46:27.450 回答
2

将原始哈希修改为如下所示可能更容易:

%lookup = (
    'Shelf' => { storage_types => [ 'Flat', 'Default'] },
    'Locker' => { storage_types => ['Valuable'] },
);

然后

%reverse_lookup = map {
       my $key = $_; 
       #$_ => $key foreach @{$lookup{$key}};
       map { $_ => $key } @${lookup{$key}};
    } keys %lookup;
于 2012-08-10T13:40:49.983 回答
1

事实证明,只要您不介意在 void 上下文中无用地使用 map(甚至比这更愚蠢的事情),您就可以使用一张地图来做到这一点:

map { @reverse_hash{split /,\s*/, $lookup{$_}} = ($_x100) } keys %lookup;

不过,它很简洁。它甚至可以工作!

于 2012-08-10T14:25:07.997 回答
1

如果您只对 感兴趣storage_types并且希望您有不可读的代码,您可以尝试:

%reverse_lookup = map { my $k = $_; map { $_ => $k } split /,\s*/, $lookup{$_}{storage_types} } keys %lookup;
于 2012-08-10T13:46:49.903 回答
0

这就是我将如何编码

use strict;
use warnings;

my %lookup = (
  Shelf => { storage_types => 'Flat, Default' },
  Locker => { storage_types => 'Valuable' },
);

my %reverse_lookup;

while ( my ($item, $info) = each %lookup ) {
  my @types = split /,\s*/, $info->{storage_types};
  $reverse_lookup{$_} = $item for @types;
}

use Data::Dump;
dd \%reverse_lookup;

输出

{ Default => "Shelf", Flat => "Shelf", Valuable => "Locker" }
于 2012-08-10T18:25:41.643 回答