从Perl 6中的数组值的哈希中检索数据

Eug*_*sky 3 perl6

我有一个包含3个元素的数组:

my @a = <x y z>;
Run Code Online (Sandbox Code Playgroud)

然后我用Array值创建一个哈希,并使其@a内容成为其值之一:

my Array %h;
%h<a> = @a;
Run Code Online (Sandbox Code Playgroud)

稍后我检索此值并将其分配给另一个数组:

my @A = %h<a>;
Run Code Online (Sandbox Code Playgroud)

但我得到的@A不是一个包含3个元素的数组,而是一个元素的数组,它本身就是一个包含3个元素的数组:

say @A;          # [[x y z]]
say @A[0].elems; # 3
Run Code Online (Sandbox Code Playgroud)

所以,%h<a>push编入@A.

我的代码中的错误在哪里?

UPD:这似乎解决了这个问题,但并没有提高我的理解力.:)

my @A = @(%h<a>);
say @A; [x y z]
Run Code Online (Sandbox Code Playgroud)

Eli*_*sen 5

发生这种情况的原因是,@a必须将数组放入容器中以允许将其存储为a中的值Hash.当存储到数组中时,容器内的某些东西将保留在容器中@A.所以,你需要的是在你分配时摆脱容器@A.您的解决方案是摆脱容器的一种方法,但这会产生一个中间体List,对于大型阵列而言可能会变得昂贵.

正如我所说,你需要摆脱容器.幸运的是,我们有一个语法:postfix <>:

my @a = <a b c>;
my %h = a => @a;
my @b = %h<a><>;  # <-- note the <> here
dd @b;    # Array @b = ["a", "b", "c"]
Run Code Online (Sandbox Code Playgroud)

如果你真的想要@b变异,这将是最有效的方式.或者,如果您想@b成为原始的别名@a,您还可以绑定:

my @a = <a b c>;
my %h = a => @a;
my @b := %h<a>;  # <-- note the := here
dd @b;    # Array @a = ["a", "b", "c"]
Run Code Online (Sandbox Code Playgroud)

请注意,dd输出现在显示@a为名称,因为它现在实际上与以下内容相同@a:@a现在也将显示任何更改,@b反之亦然.如果你还没有改变它们,那也没关系.如果在你的情况下这是真的,那么这将是最有效的方式,无论是CPU还是内存.

  • https://docs.perl6.org/language/containers#Flattening,_items_and_containers上有一些信息,但可能会有所改进.如果您这么认为,请为它创建一个文档问题:https://github.com/perl6/doc/issues (3认同)