我可以制作一个定型(固定大小)的数组:
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];...
};
}
最佳答案
How can I slice this to get any particular column or diagonal that I want?
据我所知,您目前无法将切片语法与整形数组一起使用(尽管您的“(行很容易)”注释使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数组兼容性(如果我没错的话)),则可能必须保留该数组的两个副本围绕,使用一个保留形状阵列的所需方面,另一个进行切片。
How do I turn a list of the indices in each dimension into the right thing to put in the square braces?
最终叶子之前的每个维片都必须用
;
与下一个维片分开。我尚不清楚这是因为
;
是语句分隔符(在下标内)还是列表列表指示符,还是因为如何以编程方式将索引列表转换为该形式。 (调查在继续。)And, surely there's some fancy syntax that would keep me from doing something complicated [for a diagonal slice]:
say @array[*;{$++}]; # 1 5 9 (diagonal)
;
数组下标中的第一个由[...]
分隔的字段对应于数组中的第一个维度,即数组中的行。指定
*
意味着您要包括所有行,而不是指定特定行。最后一个字段对应于下标的叶子,即要访问的实际元素。
我首先尝试仅使用
$++
而不是{$++}
,但这大概使所有元素的列为零,这是因为语言/烘烤和/或Rakudo每次对[...]
下标运算符的调用仅评估一次标量索引值。然后我推断出,如果索引是Callable,它将被调用,并且可能每行调用一次。那行得通。
我认为这对应于this code in Rakudo。
乍一看,这似乎意味着您不能使用
Callable
来计算叶子切片,并且我注意到roast'd slicing for "calculated indices"不包括对Callable
的使用。也许我只是看错了。
关于multidimensional-array - 如何在Perl 6中切片形状数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50361375/