diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/Iterator.scala | 32 | ||||
-rw-r--r-- | src/library/scala/List.scala | 40 | ||||
-rw-r--r-- | src/library/scala/Stream.scala | 18 |
3 files changed, 56 insertions, 34 deletions
diff --git a/src/library/scala/Iterator.scala b/src/library/scala/Iterator.scala index fbfd4c3e5c..d0377c5692 100644 --- a/src/library/scala/Iterator.scala +++ b/src/library/scala/Iterator.scala @@ -119,33 +119,41 @@ object Iterator { /** Create an iterator with elements * <code>e<sub>n+1</sub> = e<sub>n</sub> + step</code> * where <code>e<sub>0</sub> = start</code> - * and <code>e<sub>i</sub> < end</code>. Will return an empty range - * for nonsensical range/step arguments. + * and elements are in the range between <code>start</code> (inclusive) + * and <code>end</code> (exclusive) * * @param start the start value of the iterator * @param end the end value of the iterator * @param step the increment value of the iterator (must be positive or negative) * @return the iterator with values in range <code>[start;end)</code>. */ - def range(start: Int, end: Int, step: Int): Iterator[Int] = range(start, end, {(_:Int) + step}) + def range(start: Int, end: Int, step: Int) = new Iterator[Int] { + private var i = start + def hasNext: Boolean = (step <= 0 || i < end) && (step >= 0 || i > end) + def next(): Int = + if (hasNext) { val j = i; i = i + step; j } + else throw new NoSuchElementException("next on empty iterator") + } /** Create an iterator with elements * <code>e<sub>n+1</sub> = step(e<sub>n</sub>)</code> * where <code>e<sub>0</sub> = start</code> - * and <code>e<sub>i</sub> < end</code>. + * and elements are in the range between <code>start</code> (inclusive) + * and <code>end</code> (exclusive) * * @param start the start value of the iterator * @param end the end value of the iterator - * @param step the increment function of the iterator + * @param step the increment function of the iterator, must be monotonically increasing or decreasing * @return the iterator with values in range <code>[start;end)</code>. */ - def range(start: Int, end: Int, step: Int => Int): Iterator[Int] = - new Iterator[Int] { - private var i = start - def hasNext: Boolean = i < end - def next(): Int = - if (i < end) { val j = i; i = step(i); j } - else throw new NoSuchElementException("next on empty iterator") + def range(start: Int, end: Int, step: Int => Int) = new Iterator[Int] { + private val up = step(start) > start + private val down = step(start) < start + private var i = start + def hasNext: Boolean = (!up || i < end) && (!down || i > end) + def next(): Int = + if (hasNext) { val j = i; i = step(i); j } + else throw new NoSuchElementException("next on empty iterator") } /** Create an iterator with elements diff --git a/src/library/scala/List.scala b/src/library/scala/List.scala index c0adc30db2..c2158b9f2a 100644 --- a/src/library/scala/List.scala +++ b/src/library/scala/List.scala @@ -39,37 +39,47 @@ object List { * @param end the end value of the list * @return the sorted list of all integers in range [from;end). */ - def range(from: Int, end: Int): List[Int] = - range(from, end, 1) + def range(start: Int, end: Int): List[Int] = + range(start, end, 1) - /** Create a sorted list of all integers in a range. + /** Create a list with element values + * <code>v<sub>n+1</sub> = v<sub>n</sub> + step</code> + * where <code>v<sub>0</sub> = start</code> + * and elements are in the range between <code>start</code> (inclusive) + * and <code>end</code> (exclusive) * - * @param from the start value of the list + * @param start the start value of the list * @param end the end value of the list * @param step the increment value of the list - * @return the sorted list of all integers in range [from;end). + * @return the sorted list of all integers in range [start;end). */ - def range(from: Int, end: Int, step: Int): List[Int] = { + def range(start: Int, end: Int, step: Int): List[Int] = { val b = new ListBuffer[Int] - var i = from - while (i < end) { + var i = start + while ((step <= 0 || i < end) && (step >= 0 || i > end)) { b += i i += step } b.toList } - /** Create a sorted list of all integers in a range. + /** Create a sorted list with element values + * <code>v<sub>n+1</sub> = step(v<sub>n</sub>)</code> + * where <code>v<sub>0</sub> = start</code> + * and elements are in the range between <code>start</code> (inclusive) + * and <code>end</code> (exclusive) * - * @param from the start value of the list + * @param start the start value of the list * @param end the end value of the list - * @param step the increment function of the list - * @return the sorted list of all integers in range [from;end). + * @param step the increment function of the list, must be monotonically increasing or decreasing + * @return the sorted list of all integers in range [start;end). */ - def range(from: Int, end: Int, step: Int => Int): List[Int] = { + def range(start: Int, end: Int, step: Int => Int): List[Int] = { + val up = step(start) > start + val down = step(start) < start val b = new ListBuffer[Int] - var i = from - while (i < end) { + var i = start + while ((!up || i < end) && (!down || i > end)) { b += i i += step(i) } diff --git a/src/library/scala/Stream.scala b/src/library/scala/Stream.scala index 1415e3ad06..f16085080e 100644 --- a/src/library/scala/Stream.scala +++ b/src/library/scala/Stream.scala @@ -103,7 +103,8 @@ object Stream { * Create a stream with element values * <code>v<sub>n+1</sub> = v<sub>n</sub> + step</code> * where <code>v<sub>0</sub> = start</code> - * and <code>v<sub>i</sub> < end</code>. + * and elements are in the range between <code>start</code> (inclusive) + * and <code>end</code> (exclusive) * * @param start the start value of the stream * @param end the end value of the stream @@ -112,8 +113,8 @@ object Stream { */ def range(start: Int, end: Int, step: Int): Stream[Int] = { def loop(lo: Int): Stream[Int] = - if (lo >= end) empty - else cons(lo, loop(lo + step)) + if ((step <= 0 || lo < end) && (step >= 0 || lo > end)) cons(lo, loop(lo + step)) + else empty loop(start) } @@ -121,17 +122,20 @@ object Stream { * Create a stream with element values * <code>v<sub>n+1</sub> = step(v<sub>n</sub>)</code> * where <code>v<sub>0</sub> = start</code> - * and <code>v<sub>i</sub> < end</code>. + * and elements are in the range between <code>start</code> (inclusive) + * and <code>end</code> (exclusive) * * @param start the start value of the stream * @param end the end value of the stream - * @param step the increment function of the stream + * @param step the increment function of the stream, must be monotonically increasing or decreasing * @return the stream starting at value <code>start</code>. */ def range(start: Int, end: Int, step: Int => Int): Stream[Int] = { + val up = step(start) > start + val down = step(start) < start def loop(lo: Int): Stream[Int] = - if (lo >= end) empty - else cons(lo, loop(step(lo))) + if ((!up || lo < end) && (!down || lo > end)) cons(lo, loop(step(lo))) + else empty loop(start) } |