summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-02-06 18:43:12 +0000
committerMartin Odersky <odersky@gmail.com>2008-02-06 18:43:12 +0000
commit5ffe50c3dfc793eb983f341f4e9e816de3636a4f (patch)
treeecb40df9cbf8595bcfad682045d45ab170880b79 /src
parent11d8e2c4870d13be7b4a651495aae8fb8946d60f (diff)
downloadscala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.tar.gz
scala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.tar.bz2
scala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.zip
fixed problems with ranges
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/Iterator.scala32
-rw-r--r--src/library/scala/List.scala40
-rw-r--r--src/library/scala/Stream.scala18
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> &lt; 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> &lt; 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> &lt; 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> &lt; 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)
}