我可以从地图中返回多个Pa对齐哈希吗?

问题描述 投票:8回答:1

我正在尝试创建一个按键或值查找的哈希。要查找两种方式,我希望值为键(值为键)。

<
H He
>
    ==> map( {
        state $n = 0; $n++;
        $n     => $_.Str,
        $_.Str => $n
         } )
    ==> my %elements;

%elements.perl.say;

%elements{2}.WHAT.say;

这给了我这个奇怪的事情:

{"1\tH H\t2" => $(2 => "He", :He(2))}
(Any)

只有一对,没关系:

<
H He
>
    ==> map( {
        state $n = 0; $n++;
        $n     => $_.Str
         } )
    ==> my %elements;

%elements.perl.say;

%elements{2}.WHAT.say;

现在我得到了我想要的东西,但没有反向对:

{"1" => "H", "2" => "He"}
(Str)
perl6 feed-operator
1个回答
8
投票

你的map返回一系列List值,每个值包含两个Pair值。 将其提供给哈希不会自动将其展平,并且每个List都会成为哈希的键或值。

有几种方法可以让它做你想要的:

使用flat

您可以使用内置的flat函数来展平map的结果,以便哈希接收一系列Pairs:

<H He>
==> map {
    (state $n)++;
    +$n => ~$_,
    ~$_ => +$n
}\
==> flat()
==> my %elements;

%elements.say;          # {1 => H, 2 => He, H => 1, He => 2}
%elements{2}.WHAT.say;  # (Str)

mapflat都返回延迟序列,因此即使元素列表很大,这(理论上)也是内存有效的。

  • 旁注:我还写过+$n而不是$n,因为=> Pair构造运算符(如, List构造运算符)不会“解包”其参数 - 如果你给它一个项目容器,如$变量,它' ll直接绑定到它而不是它包含的值,这会导致下一个$n++也影响从前一次迭代返回的Pair。为对象构造运算符赋予值表达式而不是变量,避免了这种情况。

使用slip

slipflat的由内而外的版本:

<H He>
==> map {
    (state $n)++;
    slip
        +$n => ~$_,
        ~$_ => +$n
}\
==> my %elements;

map的每次迭代现在都返回一个类型为Slip的值,它就像List一样,除了它自动溶解到它成为其中一部分的任何父列表中。

重构

如果您不依赖于您的特定方法,则有两种可能更清晰的方法来生成相同的哈希:

my @keys = 1..*;
my @values = <H He>;
my %elements = flat (@keys Z=> @values), (@values Z=> @keys);

要么:

my %elements = 1..* Z=> <H He>;
push %elements, %elements.invert;

Z是“zip”元运算符)

© www.soinside.com 2019 - 2024. All rights reserved.