raku 从头开始做转子的更好方法是什么?
raku What is a better way to do rotor from the end?
如果列表末尾的数据更重要,并且我希望 :partial 列表保留在列表的开头,同时保留初始顺序,我这样做:
> 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个"reverse"操作?是否可以添加 :fromEnd 副词?
先回答最后一个问题:是的,这是可能的,但为了保持一致性,它可能会被称为 :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
方法相对便宜,因为它实际上不会移动任何值。
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 *)
。当然,你可以定义 function
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;
您可以计算 :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 * )
如果列表末尾的数据更重要,并且我希望 :partial 列表保留在列表的开头,同时保留初始顺序,我这样做:
> 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个"reverse"操作?是否可以添加 :fromEnd 副词?
先回答最后一个问题:是的,这是可能的,但为了保持一致性,它可能会被称为 :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
方法相对便宜,因为它实际上不会移动任何值。
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 *)
。当然,你可以定义 function
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;
您可以计算 :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 * )