如果列表末尾的数据更重要,并且我希望:部分列表留在列表的开头,同时保留初始顺序,我会这样做:
> my @a = (0,1,2,3,4,5,6,7,8,9);
[0 1 2 3 4 5 6 7 8 9]
> say @a.rotor(4, :partial)
((0 1 2 3) (4 5 6 7) (8 9)) # not what I want; important data at end gets cut off;
> say @a.reverse.rotor(4, :partial).reverse.map({$_.reverse});
((0 1) (2 3 4 5) (6 7 8 9)) # this is what I want
有没有办法避免这3种"反向"操作?可以加一个:fromEnd副词吗?
my @a = (0,1,2,3,4,5,6,7,8,9);
my @b = @a.rotor(4, :partial)».elems.reverse;
say @a.rotor(|@b);
您可以使用@a.rotor(2,4,4)
或更通用的@a.rotor(@a
% 4,slip 4 xx *)
。当然,您可以定义函数
multi batch ( $_, $n, :from-end($)! ) {
.rotor: .elems % $n, slip $n xx *
}
say batch ^10, 4,:from-end; #or even
say (^10).&batch(4):from-end;
先回答最后一个问题:是的,这是可能的,但为了一致性,它可能会被称为:end
,不,我认为不太可能添加它。但我可能错了:-(
我不确定你的例子有多棒,但如果你真的在处理一个数组,为什么不先用值填充它,使它可以被4整除,然后再删除它们呢:
my @a = ^10;
@a.splice(0,0, Any xx @a % 4);
say @a.batch(4); # (((Any) (Any) 0 1) (2 3 4 5) (6 7 8 9))
注意,我使用了较短的^10
(这是从0
到10
的范围,不包括端点(。我使用了更简单的batch
方法,因为我们确信不会有任何部分列表。在任何情况下,都不需要reverse
,只需要在之后检查值。
请注意,数组上的reverse
方法相对便宜,因为它实际上不会移动任何值。
您可以计算:partial
列表中剩余的元素数量。
@a.elems % 4
然后将其与所需大小的重复序列组合。
4 xx *
如果你试图简单地组合它们,就不会起作用
@a.elems % 4, 4 xx *
这是因为上面列出了两个元素。第一个是模运算的结果,第二个是无限序列。
您可以使用flat
使它们成为一个单独的序列。
flat @a.elems % 4, 4 xx *
这是生成的代码。
@a.rotor( flat @a.elems % 4, 4 xx * )