Skip to content

Commit 7368cd7

Browse files
committed
Implements missing scan left and scan right on ArrayOps.
Fixes scala/collection-strawman#544
1 parent b11db01 commit 7368cd7

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

src/library/scala/collection/ArrayOps.scala

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,61 @@ final class ArrayOps[A](val xs: Array[A]) extends AnyVal {
478478
v
479479
}
480480

481+
/** Produces an array containing cumulative results of applying the binary
482+
* operator going left to right.
483+
*
484+
* @param z the start value.
485+
* @param op the binary operator.
486+
* @tparam B the result type of the binary operator.
487+
* @return array with intermediate values.
488+
*
489+
* Example:
490+
* {{{
491+
* Array(1, 2, 3, 4).scanLeft(0)(_ + _) == Array(0, 1, 3, 6, 10)
492+
* }}}
493+
*
494+
*/
495+
def scanLeft[ B : ClassTag ](z: B)(op: (B, A) => B): Array[B] = {
496+
var v = z
497+
var i = 0
498+
var res = new Array[B](xs.length + 1)
499+
while(i < xs.length) {
500+
res(i) = v
501+
v = op(v, xs(i))
502+
i += 1
503+
}
504+
res(i) = v
505+
res
506+
}
507+
508+
509+
/** Produces an array containing cumulative results of applying the binary
510+
* operator going right to left.
511+
*
512+
* @param z the start value.
513+
* @param op the binary operator.
514+
* @tparam B the result type of the binary operator.
515+
* @return array with intermediate values.
516+
*
517+
* Example:
518+
* {{{
519+
* Array(4, 3, 2, 1).scanRight(0)(_ + _) == Array(10, 6, 3, 1, 0)
520+
* }}}
521+
*
522+
*/
523+
def scanRight[ B : ClassTag ](z: B)(op: (A, B) => B): Array[B] = {
524+
var v = z
525+
var i = xs.length - 1
526+
var res = new Array[B](xs.length + 1)
527+
res(xs.length) = z
528+
while(i >= 0) {
529+
v = op(xs(i), v)
530+
res(i) = v
531+
i -= 1
532+
}
533+
res
534+
}
535+
481536
/** Applies a binary operator to all elements of this array and a start value,
482537
* going right to left.
483538
*

test/junit/scala/collection/ArrayOpsTest.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,34 @@ class ArrayOpsTest {
4040
assertEquals(6, a.foldRight(0){ (a, b) => a+b })
4141
assertEquals(6, a.fold(0){ (a, b) => a+b })
4242
}
43+
44+
@Test
45+
def scanLeft(): Unit = {
46+
val arr = Array(2,3,4)
47+
val sums = arr.scanLeft(1)(_ + _)
48+
assertArrayEquals(Array(1, 3, 6, 10), sums)
49+
}
50+
51+
@Test
52+
def scanLeftZ(): Unit = {
53+
val arr = Array[Int]()
54+
val zero = arr.scanLeft(0)(_ + _)
55+
assertArrayEquals(Array(0), zero)
56+
}
57+
58+
@Test
59+
def scanRight(): Unit = {
60+
val arr = Array(4,3,2)
61+
val sums = arr.scanRight(1)(_ + _)
62+
assertArrayEquals(Array(10, 6, 3, 1), sums)
63+
}
64+
65+
@Test
66+
def scanRightZ(): Unit = {
67+
val arr = Array[Int]()
68+
val zero = arr.scanRight(0)(_ + _)
69+
assertArrayEquals(Array(0), zero)
70+
}
71+
72+
4373
}

0 commit comments

Comments
 (0)