diff options
-rw-r--r-- | src/library/scala/collection/TraversableLike.scala | 40 | ||||
-rw-r--r-- | test/files/pos/scan.scala | 18 | ||||
-rw-r--r-- | test/files/scalacheck/scan.scala | 17 |
3 files changed, 75 insertions, 0 deletions
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 29d3c874f6..9d65e2c224 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -612,6 +612,46 @@ self => def reduceRightOption[B >: A](op: (A, B) => B): Option[B] = if (isEmpty) None else Some(reduceRight(op)) + /** + * Produces a collection containing cummulative results of applying the operator going left to right. + * $willNotTerminateInf + * $orderDependent + * + * @tparam B the type of the elements in the resulting collection + * @tparam That the actual type of the resulting collection + * @param z the initial value + * @param op the binary operator applied to the intermediate result and the element + * @param bf $bfinfo + * @return collection with intermediate results + */ + def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { + val (_, b) = foldLeft(z, bf(repr) += z) { (acc, x) => + val next = op(acc._1, x) + (next, acc._2 += next) + } + b.result + } + + /** + * Produces a collection containing cummulative results of applying the operator going right to left. + * $willNotTerminateInf + * $orderDependent + * + * @tparam B the type of the elements in the resulting collection + * @tparam That the actual type of the resulting collection + * @param z the initial value + * @param op the binary operator applied to the intermediate result and the element + * @param bf $bfinfo + * @return collection with intermediate results + */ + def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { + val (_, b) = foldRight(z, bf(repr) += z) { (x, acc) => + val next = op(x, acc._1) + (next, acc._2 += next) + } + b.result + } + /** Sums up the elements of this collection. * * @param num an implicit parameter defining a set of numeric operations diff --git a/test/files/pos/scan.scala b/test/files/pos/scan.scala new file mode 100644 index 0000000000..98361b9167 --- /dev/null +++ b/test/files/pos/scan.scala @@ -0,0 +1,18 @@ + + + + +object Test { + + def main(args: Array[String]) { + val lst = List(1, 2, 3, 4, 5) + + assert(lst.scanLeft(0)(_ + _) == List(0, 1, 3, 6, 10, 15)) + assert(lst.scanRight(0)(_ + _) == List(0, 5, 9, 12, 14, 15)) + + val emp = List[Int]() + assert(emp.scanLeft(0)(_ + _) == List(0)) + assert(emp.scanRight(0)(_ + _) == List(0)) + } + +}
\ No newline at end of file diff --git a/test/files/scalacheck/scan.scala b/test/files/scalacheck/scan.scala new file mode 100644 index 0000000000..e9b25ce3df --- /dev/null +++ b/test/files/scalacheck/scan.scala @@ -0,0 +1,17 @@ +import org.scalacheck._ +import Prop._ +import Gen._ + + +object Test extends Properties("TraversableLike.scanLeft") { + property("scanLeft") = forAll { (xs: List[Int], z: Int) => { + val sums = xs.scanLeft(z)(_ + _) + (xs.size == 0) || sums.zip(sums.tail).map(x => x._2 - x._1) == xs + }} +} + + + + + + |