如何在Raku中无限期地和懒惰地循环浏览列表?

问题描述

主要是为了了解Raku有多棒。

问题

是否有内置方法将获取列表并无限期地循环遍历,例如生成惰性列表

a,b,c,a,...
(a,c)

?列表中的documentation中的任何内容似乎都无法解决问题。

可能的解决方案

我至少可以想到几个。

更扎实的方法是在惰性范围@array[<variable> mod length-of-@array]map 0..Inf。在perl6 REPL中:

> my @ar=<a b c>
[a b c]
> (0..Inf).map({ @ar[$_ % @ar.elems] }).[0..100]
(a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a ...)

一个更酷的解决方案(我认为)是让您首先将列表变成slip,然后将repetition operator无限期应用于该单据:

> my @ar=<a b c>
[a b c]
> (|@ar xx *).[0..100]
(a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a ...)

结论

即使我可以实现这一目标(尤其是最后一个解决方案非常精妙且令人满足),但我想知道的是,我是否缺少为此目的专门内置的任何东西。


编辑回复:接受的答案

这是对@Brad Gilbert的回答的详细说明。 «~»运算符将string concatenation ~包装在« » hyper operator中,这导致将包装的二进制运算符应用于从两个列表中顺序选择的元素。>

因此,要实现我想要的目标(将列表循环到所需的长度,例如100),

<a b c> <<~>> ("" xx 100)

这产生

(a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a)

(100个条目)。它确实有一些缺点:

  • 由于~
  • 的应用,它将列表项强制转换为字符串
  • 它实际上并不会产生一个懒惰的无限列表:
<a b c> <<~>> ("" xx *)

返回

List on right side of hyperop of infix:<~> is known to be infinite
  in block <unit> at <unknown file> line 1

解决方法

当它写得这么短时,为什么还要为此添加一个功能。特别是因为这可能是罕见的事件,您需要这样的东西。

|< a b c > xx *

有一个例外,如果您使用«~»之类的东西,它将为您扩展。

< a b c > «~» (1..10)
# (a1 b2 c3 a4 b5 c6 a7 b8 c9 a10)
,

您的第一个“扎扎实实”的示例可以写成(^Inf).map({ @ar[$_ % *] })

此外,滑动和重复也可以,但仅适用于大小合理的列表。

sub bad-cycle(@xs) {
    |@xs xx Inf
}

my $big-list = ^1e6;
say bad-cycle($big-list).head(100);    # Hangs for several seconds

更好的选择是上面显示的地图,或者像这样的gather循环

sub cycle(@xs) {
    gather loop { .take for @xs }
}

say cycle($big-list).head(100);    # Instant output
,

我不知道我是否理解这个问题。但是据我了解,您需要一种在模式之后生成无限列表的方法。好吧,如果那是问题 “ Think in Raku”一书中的第14.5部分提供了可能有所帮助的内容(改编了斐波那契数列的用法)

("a","b","c",-> $a,$b,$c {$a} ...* )

此元素是纯列表,如果您想要提取值,则需要列表上更常规的内容(例如分配和提取值)

my @list = ("a",$c {$a} ...* )
@list[0..100]
@list[91]

我认为在 Inf 上下文中使用map并不是一个好主意,但是请告诉我是否错过了一些事情,我仍然在学习这种很棒的语言!!

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...