我可以制作一个形状(固定大小)的数组:
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];...
};
}
答案 0 :(得分:5)
如何将其切片以获得我想要的任何特定列或对角线?
据我所知,你现在不能使用带有形状数组的切片语法(尽管你的“(行很容易)”注释会让我感到困惑,每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)
;
数组下标中的第一个[...]
分隔字段对应于数组中的第一个维度,即数组中的行。
指定*
表示您想要包含所有行而不是指定特定行。
最后一个字段对应于下标的叶子,即要访问的实际元素。
我首先尝试的只是$++
而不是{$++}
,但这给了我所有元素的第0列,大概是因为语言/ roast和/或Rakudo每次调用时只评估标量索引值一次{1}}下标运算符。
然后我推断如果索引是Callable,它将被调用,并且每行可能会调用一次。这很有用。
我认为这与this code in Rakudo对应。
乍一看,这似乎意味着您无法使用[...]
来计算叶片,我注意到roast'd slicing for "calculated indices"不包括使用Callable
。也许我只是没有正确看待它。
答案 1 :(得分:1)
您可能已经看到它返回尚未实现的错误(已插入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
或宏(当它们最终被实现时,当然......)