从一个迭代器创建n个迭代器

时间:2016-04-04 16:04:44

标签: scala

我想使用'duplicate'

从scala中创建一个迭代器

提出了那段代码:

def getNIterators[T](it: Iterator[T], n: Int) : Seq[Iterator[T]] = {
  getNMoreIterators(Seq(it), n-1)
}

private def getNMoreIterators[T](seq: Seq[Iterator[T]], n: Int) : Seq[Iterator[T]] = {
if (n <= 0) return seq else {
  val (it1, it2) = seq.head.duplicate
  Seq(it1, it2) ++ getNMoreIterators(seq.tail, n-1)
}
}

我可以将其改进为尾部监控或更有效的方法吗?

2 个答案:

答案 0 :(得分:1)

You are actually destroying the current Iterator and getting 2 new in return. I think it would me more efficient to just destroy Iterator once and put it in a Seq, getting iterators from there (that's just an intuition, I didn't bemchmark it).

def getNIterators[A](it: Iterator[A], n: Int) : Seq[Iterator[A]] = {
  val seq = it.toSeq
  Seq.fill(n)(seq.iterator)
}

You might want to read about problems with duplicate here: How to copy iterator in Scala? and here: How to clone an iterator?

Edit:

Ok then, if you don't want to consume whole iterator in the beginning, consider using a Stream

def getNIterators[A](it: Iterator[A], n: Int) : Seq[Iterator[A]] = {
  val seq = it.toStream
  Seq.fill(n)(seq.iterator)
}

It will consume Iterator as needed (except for the head, it will be consumed immidietly), and all the Iterators are independent.

scala> (1 to 4).iterator.map(s => {println(s); s})
res12: Iterator[Int] = non-empty iterator

scala> getNIterators(res12, 4)
1
res13: Seq[Iterator[Int]] = List(non-empty iterator, non-empty iterator, non-empty iterator, non-empty iterator)

scala> res13.map(_.next)
res14: Seq[Int] = List(1, 1, 1, 1)

scala> res13.map(_.next)
2
res15: Seq[Int] = List(2, 2, 2, 2)

scala> res13.map(_.next)
3
res16: Seq[Int] = List(3, 3, 3, 3)

scala> res13.map(_.next)
4
res17: Seq[Int] = List(4, 4, 4, 4)

答案 1 :(得分:0)

怎么样:

def getNIterators[T](it: Iterator[T], n: Int) : Seq[Iterator[T]] = {
   (1 to n).map(_ => it.duplicate._2)
}