我该如何在Perl 6中切片一个形状数组?

9

我可以创建一个具有固定大小的数组(shaped array):

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
在切片一个形状数组的上下文中,你说“行很容易”这个评论让我感到困惑。当我声明一个形状数组并尝试有效地访问一个切片(既不是整个数组也不是单个元素)时,我会收到错误消息“部分维度的形状数组视图尚未实现。抱歉。”我认为这个错误消息很差,因为我正在尝试完全维度的切片,但无论如何,我不明白你怎么能切割行。 - raiph
2个回答

5
我应该如何切片以获取我想要的任何特定列或对角线?
据我所知,目前无法在形状数组中使用切片语法(尽管您的“(行很容易)”评论使我困惑,参见我在您的帖子上的评论)。显然的解决方案是放弃形状并使用切片语法:
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)

如果你想保留使用shaped数组的边界检查安全性(以及如果我没记错的话,使用shaped本地数组的C数组兼容性),那么你可能需要保留两份数组副本,其中一份用于保留shaped数组的期望方面,另一份用于切片。
“如何将每个维度中的索引列表转换为放入方括号的正确内容?
在最后一个叶子之前的每个维度切片必须由“;”分隔开。
我还不清楚这是因为“;”是语句分隔符(在下标中)还是列表-列表指示符,以及如何将索引列表以编程方式转换成该形式。(调查仍在进行中。)
“而且,肯定有一些花哨的语法可以让我避免做一些复杂的事情[对于对角线切片]:”
say @array[*;{$++}];   # 1 5 9 (diagonal)
[...] 数组下标中第一个用分号分隔的字段对应于数组中的第一个维度,即数组中的行。
指定 * 意味着您想包括所有行而不是指定特定的行。
最后一个字段对应于下标的叶子节点,即要访问的实际元素。
我首先尝试了只使用$++ 而不是 {$++} ,但这给我所有元素的零列,可能是因为语言/烤肉和/或 Rakudo 在每次调用[...]下标运算符时仅计算一次标量索引值。
然后我推断,如果索引是 Callable ,它将被调用,并且可能会在每一行上调用一次。 这样就可以工作了。
我认为这对应于Rakudo中的此代码
乍一看,这似乎意味着您无法使用 Callable 计算叶片切片,我注意到“计算索引”进行的切片不包括使用 Callable 。 也许我只是看错了。

我正在寻找适用于一般情况的东西,而不是偶然适用于某个特定情况的东西。 - brian d foy
@briandfoy 对,我认为这个东西目前还比较薄弱。请看我的最后一次编辑。 - raiph
@briandfoy 顺便说一下,我仍然对你在问题中提到的“(行很容易)”感到困惑,就像我在评论中所说的那样。 - raiph
1
@jjmerelo 我的解释足够吗? - raiph

1

你可能已经看到过返回一个尚未实现错误的情况(这是为了解决此错误而插入;

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;

通过查看主题摘要,我认为该方法并没有明确定义。因此,最终你可能需要使用EVAL或宏(当它们被实现时...)。

1
据我所知,我没有做任何“部分”的事情。这个错误与我试图完成的任务无关。 - brian d foy
2
部分错误与您的任务有密切关系,但绝对不清楚。本质上,这种下标形式对于原始数组并不存在。`> my @shaped[3;3] = [< 1 2 3 >;< 4 5 6 >;< 7 8 9 >] [[1 2 3] [4 5 6] [7 8 9]]
@shaped[1;*] 部分维度的形状阵列视图尚未实现。抱歉。 in block <unit> at <unknown file> line 1
my @unshaped = [< 1 2 3 >;< 4 5 6 >;< 7 8 9 >] [(1 2 3) (4 5 6) (7 8 9)] @unshaped[1;*] (4 5 6)`
- Matt Oates

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接