如何在Perl 6中对定形(固定大小)数组进行切片?
嘿,我来帮你搞定Raku里定形数组的切片和索引问题!下面分点给你讲清楚:
Raku 定形数组切片与索引技巧
1. 提取特定列或对角线的简单方法
拿特定列超简单
对于你定义的3x3定形数组,要提取某一列的话,用*通配符表示该维度的所有元素,再指定列索引就行。比如要拿第二列(索引是1):
my @array[3;3] = ( <1 2 3>, <4 5 6>, <7 8 9> ); say @array[*;1]; # 输出:(2 5 8)
这里*匹配所有行,1锁定列,组合起来就直接拿到整列元素了。
主对角线提取的简洁写法
主对角线的元素都是行索引等于列索引的,Raku里用[Z]操作符就能轻松配对这些索引:
# 通用版,适配任意N维方阵的主对角线 my @indices = [Z] @array.shape.map: { 0..^$_ }; my @diagonal = @array[@indices]; say @diagonal; # 输出:(1 5 9)
如果是明确的3x3数组,还能再简化成:
my @diagonal = @array[[Z] (0..2, 0..2)];
2. 把索引列表转换成数组能用的索引形式
如果你有一组多维索引(比如[(0,1), (1,2), (2,0)]),直接把这个列表丢进数组的方括号里就行——Raku会自动把每个子列表解析成对应维度的索引:
my @target-indices = [(0,1), (1,2), (2,0)]; my @result = @array[@target-indices]; say @result; # 输出:(2 6 7)
要是你的索引是分维度的序列(比如行索引(0,1,2)、列索引(1,2,0)),用[Z]把它们配对后再传进去,效果是一样的:
my @rows = 0..2; my @cols = 1,2,0; my @result = @array[[Z] @rows, @cols];
3. 简化你那套复杂的对角线实现
你之前写的gather代码其实可以大幅简化,而且注释里的$_[0];$_[1];...根本不用额外处理——Raku会自动把$_(那个索引列表)解析成多维索引。不过我们完全可以抛弃gather,用更清爽的写法:
推荐方法:用[Z]配对索引
一行代码搞定主对角线提取,既通用又简洁:
my @diagonal = @array[[Z] @array.shape.map: { 0..^$_ }];
备选方法:通过keys筛选索引
如果你想更直观地筛选,也可以用数组的keys属性(它会返回所有多维索引的序列),然后挑出索引相等的元素:
my @diagonal = @array.grep({ .key[0] == .key[1] })».value;
另外,要是你还想用gather的写法,其实原代码稍微调整下就能正常跑:
my @diagonal = gather { my @ends = @array.shape.map: { (0 ..^ $^a).List }; for [Z] @ends { take @array[$_]; # 这里直接用$_就行,Raku会自动解析成多维索引 }; } say @diagonal; # 输出:(1 5 9)
完全没问题,之前的担心是多余的~
内容的提问来源于stack exchange,提问作者brian d foy
相关产品推荐
相关产品推荐

