diff options
author | Donna Malayeri <lindydonna@gmail.com> | 2009-11-26 16:56:02 +0000 |
---|---|---|
committer | Donna Malayeri <lindydonna@gmail.com> | 2009-11-26 16:56:02 +0000 |
commit | 207b303157385b210e78c76c2d6f95dbe45cddb2 (patch) | |
tree | 254fb2214c3dd7e149fe92d6cc402fd66567f216 | |
parent | 8284808cf62a87a1ad682cc64027d1bd2c444d18 (diff) | |
download | scala-207b303157385b210e78c76c2d6f95dbe45cddb2.tar.gz scala-207b303157385b210e78c76c2d6f95dbe45cddb2.tar.bz2 scala-207b303157385b210e78c76c2d6f95dbe45cddb2.zip |
Improved fix for #2552
-rw-r--r-- | src/library/scala/collection/Iterator.scala | 58 | ||||
-rw-r--r-- | test/files/run/bug2552.check | 1 |
2 files changed, 26 insertions, 33 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 74109a0e81..8f49bbd0e4 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -351,24 +351,23 @@ trait Iterator[+A] { self => * @param p the predicate used to filter the iterator. * @return the elements of this iterator satisfying <code>p</code>. */ - def filter(p: A => Boolean): Iterator[A] = { - val self = buffered - new Iterator[A] { - var computedHasNext = false - private def skip() = { - while (self.hasNext && !p(self.head)) self.next() - computedHasNext = self.hasNext - } - def hasNext = { if (!computedHasNext) skip(); computedHasNext } - def next() = { - if (!computedHasNext) - skip() - computedHasNext = false - self.next() - } - } + def filter(p: A => Boolean): Iterator[A] = new Iterator[A] { + private var hd: A = _ + private var hdDefined: Boolean = false + + def hasNext: Boolean = hdDefined || { + do { + if (!self.hasNext) return false + hd = self.next() + } while (!p(hd)) + hdDefined = true + true + } + + def next() = if (hasNext) { hdDefined = false; hd } else empty.next() } + /** !!! Temporary, awaiting more general implementation. * ... better wait longer, this fails once flatMap gets in the mix. */ @@ -406,23 +405,18 @@ trait Iterator[+A] { self => * @param p the predicate used to filter the iterator. * @return the longest prefix of this iterator satisfying <code>p</code>. */ - def takeWhile(p: A => Boolean): Iterator[A] = { - val self = buffered - new Iterator[A] { - var computedHasNext = false - - def hasNext = { - val result = computedHasNext || (self.hasNext && p(self.head)) - computedHasNext = result - result - } - - def next() = { - val result = (if (computedHasNext || hasNext) self else empty).next() - computedHasNext = false - result - } + def takeWhile(p: A => Boolean): Iterator[A] = new Iterator[A] { + private var hd: A = _ + private var hdDefined: Boolean = false + private var tail: Iterator[A] = self + + def hasNext = hdDefined || tail.hasNext && { + hd = tail.next() + if (p(hd)) hdDefined = true + else tail = Iterator.empty + hdDefined } + def next() = if (hasNext) { hdDefined = false; hd } else empty.next() } /** Partitions this iterator in two iterators according to a predicate. diff --git a/test/files/run/bug2552.check b/test/files/run/bug2552.check index 774e360d13..1deeae772f 100644 --- a/test/files/run/bug2552.check +++ b/test/files/run/bug2552.check @@ -28,7 +28,6 @@ true 1 p(2) false -p(2) false p(0) true |