如何在 Perl 6 中对形状数组进行切片?

Posted

技术标签:

【中文标题】如何在 Perl 6 中对形状数组进行切片?【英文标题】:How can I slice a shaped array in Perl 6? 【发布时间】:2018-10-25 22:43:40 【问题描述】:

我可以制作一个形状(固定大小)的数组:

my @array[3;3] = (
    < 1 2 3 >,
    < 4 5 6 >,
    < 7 8 9 >
    );

say @array;       # [[1 2 3] [4 5 6] [7 8 9]]
say @array[1;1];  # 5

如何将其切片以获得我想要的任何特定列或对角线(行很容易)?

如何将每个维度中的索引列表转换为放入方括号中的正确内容?

而且,肯定有一些花哨的语法可以阻止我做一些复杂的事情:

my @diagonal = gather 
    my @ends = @array.shape.map:  (0 ..^ $^a).List ;
    for [Z] @ends 
        take @array[ $_ ] # how do I make that $_[0];$_[1];...
        ;
    

【问题讨论】:

我对您在切片形状数组的上下文中“行很容易”的评论感到困惑。当我声明一个成形数组并尝试有效访问一个切片(既不是整个数组也不是单个元素的任何内容)时,我收到错误消息“成形数组的部分尺寸视图尚未实现。抱歉。”我认为错误消息很差,因为我正在尝试全尺寸切片,但无论如何,我不明白您如何甚至可以切片行。 【参考方案1】:

我怎样才能得到我想要的任何特定的列或对角线?

据我所知,您目前不能将切片语法与成形数组一起使用(尽管您的“(行很容易)”评论让我很困惑 my comment on your post)。

显而易见的解决方案是删除形状并使用切片语法:

my @array = ( < 1 2 3 >, < 4 5 6 >, < 7 8 9 > );

say @array[1];         # 4 5 6 (second row)
say @array[1;*];       # same
say @array[*;1];       # 2 5 8 (second column)

如果您想保留使用成形数组的边界检查安全性(和/或成形本机数组的 C 数组兼容性,如果我是对的话),那么您可能必须保留两个副本周围的阵列,使用一个来保留所需的形状阵列的方面,另一个来切片。

如何将每个维度中的索引列表转换为正确放入方括号的内容?

最后一个叶子之前的每个维度切片必须用;与下一个分隔。

我还不清楚这是因为 ; 是语句分隔符(在下标内)还是列表指示符,也不清楚如何以编程方式将索引列表转换为该形式。 (调查仍在继续。)

而且,肯定有一些花哨的语法可以阻止我做一些复杂的事情[对于对角线切片]:

say @array[*;$++];   # 1 5 9 (diagonal)

[...]数组下标中的第一个;分隔字段对应数组中的第一个维度,即数组中的行。

指定* 表示您希望包含所有行而不是指定特定行。

最后一个字段对应于下标的叶子,即要访问的实际元素。

我第一次尝试只尝试$++ 而不是$++ 但这给了我所有元素的列为零大概是因为语言/烘焙和/或 Rakudo 每次调用 [...] 下标运算符时只评估一次标量索引值.

然后我推断如果索引是Callable,它将被调用,并且可能每行调用一次。这很有效。

我认为这对应于this code in Rakudo。

乍一看,这似乎意味着您不能使用Callable 来计算叶切片,我注意到roast'd slicing for "calculated indices" 不包括使用Callable。也许我只是看的不对。

【讨论】:

我正在寻找适用于一般情况的东西,而不是偶然适用于其中一种情况的东西。 @briandfoy 对。我认为这些东西目前很弱。查看我的上一次编辑。 @briandfoy Fwiw 根据我对您问题的评论,我仍然对您的“(行很容易)”感到困惑。 @jjmerelo 我的解释够吗?【参考方案2】:

您可能已经看到,它返回一个尚未实现错误(插入to solve this bug;

Partially dimensioned views of shaped arrays not yet implemented. Sorry.

在这种情况下,最好只取消数组形状并使用更传统的方法:

use v6;

my @array = (
    < 1 2 3 >,
    < 4 5 6 >,
    < 7 8 9 >
    );

my @diagonal = gather 
    my @ends = ((0,0),(1,1),(2,2));
    for @ends -> @indices 
        take @array[ @indices[0] ][@indices[1]];
    ;

say @diagonal;

通过查看the synopsis on the subject,我想说这种方法并没有真正指定。所以当一切都说完了,你可能不得不使用EVAL 或宏(当它们最终实现时,当然......)

【讨论】:

据我所知,我没有做任何“部分”的事情。该错误对我尝试执行的任务没有任何意义。 部分错误与您的任务有关一切,但绝对不清楚。本质上,本机形状数组尚不存在这种形式的下标。 &gt; my @shaped[3;3] = [&lt; 1 2 3 &gt;;&lt; 4 5 6 &gt;;&lt; 7 8 9 &gt;] [[1 2 3] [4 5 6] [7 8 9]] &gt; @shaped[1;*] Partially dimensioned views of shaped arrays not yet implemented. Sorry. in block &lt;unit&gt; at &lt;unknown file&gt; line 1 &gt; my @unshaped = [&lt; 1 2 3 &gt;;&lt; 4 5 6 &gt;;&lt; 7 8 9 &gt;] [(1 2 3) (4 5 6) (7 8 9)] &gt; @unshaped[1;*] (4 5 6)

以上是关于如何在 Perl 6 中对形状数组进行切片?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Excel VBA 中对数组进行切片?

如何在JavaScript / Jquery中对另一个数组中已经存在的数组元素进行切片[重复]

如何在 TensorFlow 中对数据集进行切片?

如何在 Perl 6 中对散列进行排序

如何在 Javascript 中对对象进行切片?

如何在 numba CUDA 中对行进行切片?