This is mostly to geek out on how awesome Raku is.
Question
Are there built-in methods that will take a list and cycle through it indefinitely, producing, say, the lazy list
a, b, c, a, b, c, ...
out of (a, b, c)
? Nothing in the documentation on lists seems to obviously do the trick.
Possible solutions
I can think of at least a couple.
The more plodding down-to-earth method would be to map @array[<variable> mod length-of-@array]
over the lazy range 0..Inf
. In the 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 ...)
A cooler (I think) solution would have you first turn your list into a slip, and then apply the repetition operator to that slip indefinitely:
> 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 ...)
Conclusion
Even though I can achieve this (and the last solution in particular is very pithy and satisfying), what I am wondering is whether I'm missing anything built in specifically for this purpose.
Edit Re: the accepted answer
This is to elaborate slightly on the answer by @Brad Gilbert. The «~»
operator wraps string concatenation ~
in the « »
hyper operator, which results in applying the wrapped binary operator to elements selected sequentially from the two lists.
So to achieve what I wanted (list-cycling to a desired length, like say 100), one would do
<a b c> <<~>> ("" xx 100)
This produces
(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 entries). It does have a couple of drawbacks though:
~
<a b c> <<~>> ("" xx *)
returns
List on right side of hyperop of infix:<~> is known to be infinite
in block <unit> at <unknown file> line 1
When it can be written this short, why add a feature just for that. Especially since it is probably a rare event that you would need such a thing.
|< a b c > xx *
Well there is one exception, if you use something like «~»
it extend it out for you.
< a b c > «~» (1..10)
# (a1 b2 c3 a4 b5 c6 a7 b8 c9 a10)
I don't know if I understood the problem. But what I understood that you need a method to produce infinite list following a pattern. Well if that's the problem in the book "Think in Raku" comes with something that may help, in the part 14.5 (adapted from how to do a Fibonacci sequence)
("a","b","c", -> $a, $b, $c {$a} ...* )
this element is the pure-list, if you want the extract values you need something like more conventional on list (like assign & extract values)
my @list = ("a","b","c", -> $a, $b, $c {$a} ...* )
@list[0..100]
@list[91]
I think that's it's not good idea using map in a Inf context, but please tell me if I missed something, i still learning about this awesome language too !!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With