我想使用'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)
}
}
我可以将其改进为尾部监控或更有效的方法吗?
答案 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?
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)
}