6

如果列表末尾的数据更重要,并且我希望 :partial list 保留在列表的开头,同时保留初始顺序,我会这样做:

> 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 副词?

4

4 回答 4

6

你可以使用@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;
于 2020-04-30T11:40:43.857 回答
6
my @a = (0,1,2,3,4,5,6,7,8,9);
my @b = @a.rotor(4, :partial)».elems.reverse;
say @a.rotor(|@b);
于 2020-04-30T09:27:25.847 回答
3

先回答最后一个问题:是的,有可能,但可能会要求: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(范围从0to 10,不包括端点)。而且我使用了更简单的batch方法,因为我们确信不会有任何部分列表。在任何情况下,都不reverse需要,只需在之后检查值。

请注意,reverse数组上的方法相对便宜,因为它实际上并不移动任何值。

于 2020-04-30T09:07:04.483 回答
1

您可以计算: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 * )
于 2020-05-07T15:24:07.383 回答