迭代循环方式

时间:2010-07-15 13:52:39

标签: scala scala-2.8 loops circular-list

我需要迭代List但循环方式。我还需要在列表中添加新元素并迭代所有元素(旧元素和新闻元素),我该怎么做?他们有没有数据结构?

4 个答案:

答案 0 :(得分:19)

一种选择是使用Stream类来创建一个惰性,循环,无限的序列:

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

scala> Stream.continually(values.toStream).flatten.take(9).toList
res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3)

或者这样:

val values = List(1, 2, 3)

def circularStream(values: List[Int],
                   remaining: List[Int] = List()): Stream[Int] = {

  if (remaining.isEmpty)
    circularStream(values,values)
  else
    Stream.cons(remaining.head, circularStream(values, remaining.drop(1)))
}

circularStream(values).take(9).toList //Same result as example #1

答案 1 :(得分:10)

def forever:Stream[Int] = Stream(1,2,3) append forever

答案 2 :(得分:7)

这种事情确实值得在标准流库中,但似乎并非如此。 dbryne对流的回答效果很好,或者如果你喜欢它的for-comprehension形式

val listToRepeat:List[Foo]
val forever:Stream[Foo] = for(x<-Stream.continually(1); y<-listToRepeat) yield y

即使您忽略了值,第一个流生成器也会让事情永远持续下去。第二个生成器被隐式地展平为你想要的无限流。

答案 3 :(得分:6)

我想也许这就是你想要的;即使在迭代时,也能够将新元素添加到列表中。代码很难看但似乎有效。

import scala.collection.mutable.Queue

class Circular[A](list: Seq[A]) extends Iterator[A]{

  val elements = new Queue[A] ++= list
  var pos = 0

  def next = {
    if (pos == elements.length) 
      pos = 0
    val value = elements(pos)
    pos = pos + 1
    value
  }

  def hasNext = !elements.isEmpty
  def add(a: A): Unit = { elements += a }
  override def toString = elements.toString

}

你可以像这样使用它:

scala> var circ = new Circular(List(1,2))
res26: Circular[Int] = Queue(1,2)
scala> circ.next
res27: Int = 1
scala> circ.next
res28: Int = 2
scala> circ.next
res29: Int = 1
scala> circ.add(5)
scala> circ.next
res30: Int = 2
scala> circ.next
res31: Int = 5
scala> circ
res32: Circular[Int] = Queue(1,2,5)