bri*_*foy 8 perl6 feed-operator
我正在尝试创建一个按键或值查找的哈希.要查找两种方式,我希望值为键(值为键).
<
H He
>
==> map( {
state $n = 0; $n++;
$n => $_.Str,
$_.Str => $n
} )
==> my %elements;
%elements.perl.say;
%elements{2}.WHAT.say;
Run Code Online (Sandbox Code Playgroud)
这给了我这个奇怪的事情:
{"1\tH H\t2" => $(2 => "He", :He(2))}
(Any)
Run Code Online (Sandbox Code Playgroud)
只有一对,没关系:
<
H He
>
==> map( {
state $n = 0; $n++;
$n => $_.Str
} )
==> my %elements;
%elements.perl.say;
%elements{2}.WHAT.say;
Run Code Online (Sandbox Code Playgroud)
现在我得到了我想要的东西,但没有反向对:
{"1" => "H", "2" => "He"}
(Str)
Run Code Online (Sandbox Code Playgroud)
您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)
Run Code Online (Sandbox Code Playgroud)
两者都返回map并flat返回延迟序列,因此即使元素列表很大,这(理论上)也是内存有效的.
+$n而不是$n因为=>Pair构造运算符(比如,List构造运算符)没有"解包"它的参数 - 如果你给它一个项容器如$变量,它将直接绑定到它而不是包含在其中的值,这会导致下一个$n++也影响Pair从上一次迭代返回的值.为对象构造运算符赋予值表达式而不是变量,避免了这种情况.slipslip是由内而外的版本flat:
<H He>
==> map {
(state $n)++;
slip
+$n => ~$_,
~$_ => +$n
}\
==> my %elements;
Run Code Online (Sandbox Code Playgroud)
的每次迭代map现在返回类型的值Slip,这是一样List,除了它自动溶解到它变得的一部分的任何父列表.
如果您不依赖于您的特定方法,则有两种可能更清晰的方法来生成相同的哈希:
my @keys = 1..*;
my @values = <H He>;
my %elements = flat (@keys Z=> @values), (@values Z=> @keys);
Run Code Online (Sandbox Code Playgroud)
要么:
my %elements = 1..* Z=> <H He>;
push %elements, %elements.invert;
Run Code Online (Sandbox Code Playgroud)
(Z是"zip"元运算符)