Scala,无限重复有限列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2097851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:52:05  来源:igfitidea点击:

Scala, repeat a finite list infinitely

listscalastreaminfinite

提问by Felix

I want to use Stream class in scala to repeat a given list infinitely.

我想在 Scala 中使用 Stream 类来无限重复给定的列表。

For example the list (1,2,3,4,5) I want to create a stream that gives me (1,2,3,4,5,1,2,3,4,5,1,2,3....)

例如列表 (1,2,3,4,5) 我想创建一个流,给我 (1,2,3,4,5,1,2,3,4,5,1,2,3 ....)

So that I can wrap the take operation. I know this can be implemented in other ways, but I wanna do it this way for some reason, just humor me :)

这样我就可以包装 take 操作。我知道这可以通过其他方式实现,但出于某种原因我想这样做,只是幽默我:)

So the idea is that with this infinite cycle created from some list, I can use take operation, and when it reaches the end of the list it cycles.

所以这个想法是,通过从某个列表创建的这个无限循环,我可以使用 take 操作,当它到达列表的末尾时它会循环。

How do I make a stream which simply repeats a given list?

如何制作一个简单地重复给定列表的流?

回答by retronym

Very similar to @Eastsun's, but a bit more intention revealing. Tested in Scala 2.8.

与@Eastsun 的非常相似,但更能揭示意图。在 Scala 2.8 中测试。

scala> val l  = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)

scala> Stream.continually(l.toStream).flatten.take(10).toList
res3: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)

Alternatively, with Scalaz:

或者,使用 Scalaz:

scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)

scala> l.toStream.repeat[Stream].join.take(10).toList
res7: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)

回答by Volkan Yaz?c?

An alternative method is concatenating the .toStreamof the input with itself recursively. That is,

另一种方法是.toStream递归地将输入的 与自身连接起来。那是,

scala> val xs: Stream[Int] = List(1, 2, 3).toStream #::: xs
xs: Stream[Int] = Stream(1, ?)

scala> xs.take(10).toList
res1: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)

回答by Eastsun

There is a simple way with Stream#flatten in scala 2.8

Stream#flatten 在 Scala 2.8 中有一个简单的方法

Welcome to Scala version 2.8.0.r20542-b20100116020126 (Java HotSpot(TM) Client VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def cycle[T](seq: Seq[T]) = Stream.from(0).flatten(_ => seq)
cycle: [T](seq: Seq[T])scala.collection.immutable.Stream[T]

scala> cycle(1::2::3::Nil)
res0: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> res0.take(10)
res1: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> res0.take(10).toList
res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)

回答by Daniel Spiewak

Here's an implementation which doesn't assume that lengthis efficient:

这是一个不假设length有效的实现:

def rep[A](seq: Seq[A]) = {
  def inner(proj: Seq[A]): Stream[A] = {
    if (proj.isEmpty)
      inner(seq)
    else
      Stream.cons(proj.first, inner(proj drop 1))
  }

  if (seq.isEmpty)
    Stream.empty
  else
    inner(seq)
}

This should run in constant time for any Seq(including Listor even Stream) and only imposes a constant time overhead to populate each element. Also, it works even for infinite sequences. So, you can call repon an infinite Streamand the resulting Streamwill be equivalent to the input.

这应该在任何Seq(包括List或什至Stream)的恒定时间内运行,并且仅施加恒定的时间开销来填充每个元素。此外,它甚至适用于无限序列。因此,您可以调用rep一个无穷大Stream,结果Stream将等同于输入。

回答by Justin W

Stolen blatently from the excellent Scala by Examplebook, chapter 12, and with a few modifications:

从优秀的Scala by Example书第 12 章公然窃取,并做了一些修改:

def repeatedSeq(idx: Int, lst:Seq[Int]): Stream[Int] = Stream.cons(lst(idx), repeatedSeq((idx + 1)%lst.length, lst))

for(i <- repeatedSeq(1,List(1,1,2,3,5))) println(i)

This works for all Seq types (unless they can't be read from multiple times, of course). Might not be efficient if the .length call is slow. Tested in Scala 2.7.7.

这适用于所有 Seq 类型(当然,除非它们不能被多次读取)。如果 .length 调用很慢,则可能效率不高。在 Scala 2.7.7 中测试。