diff --git a/src/main/scala/strawman/collection/Iterable.scala b/src/main/scala/strawman/collection/Iterable.scala index 801e02cbfe..cf5f7526e2 100644 --- a/src/main/scala/strawman/collection/Iterable.scala +++ b/src/main/scala/strawman/collection/Iterable.scala @@ -846,7 +846,18 @@ trait IterableOps[+A, +CC[X], +C] extends Any { * `List("a", "b", "c").zipWithIndex == List(("a", 0), ("b", 1), ("c", 2))` */ def zipWithIndex: CC[(A @uncheckedVariance, Int)] = fromIterable(View.ZipWithIndex(toIterable)) - + + /** Returns a $coll formed by zipping this $coll and another iterable collection, + * and applying `f` to each pair. + * + * Semantically equivalent to `this.zip(that).map(t => f(t._1, t._2))` + * + * @param that The other iterable to zip with + * @param f The function used to reduce each zipped pair + * @return A new collection + */ + def zipWith[B, R](that: Iterable[B])(f: (A, B) => R): CC[R] = fromIterable(View.ZipWith(toIterable, that, f)) + /** Converts this $coll of pairs into two collections of the first and second * half of each pair. * diff --git a/src/main/scala/strawman/collection/Iterator.scala b/src/main/scala/strawman/collection/Iterator.scala index 65018da10e..c52db7cab8 100644 --- a/src/main/scala/strawman/collection/Iterator.scala +++ b/src/main/scala/strawman/collection/Iterator.scala @@ -629,6 +629,17 @@ trait Iterator[+A] extends IterableOnce[A] { self => ret } } + + /** Creates an iterator that zips each element produced by this iterator + * with one produced by the iterator of `that` and then applies `f` to each pair. + * + * @return a new iterator containing the output of `f` for each zipped pair + */ + def zipWith[B, R](that: IterableOnce[B])(f: (A, B) => R): Iterator[R] = new Iterator[R] { + val thatIterator = that.iterator() + def hasNext = self.hasNext && thatIterator.hasNext + def next() = f(self.next(), thatIterator.next()) + } def sameElements[B >: A](that: IterableOnce[B]): Boolean = { val those = that.iterator() diff --git a/src/main/scala/strawman/collection/View.scala b/src/main/scala/strawman/collection/View.scala index e3ed56cf1b..4396b98473 100644 --- a/src/main/scala/strawman/collection/View.scala +++ b/src/main/scala/strawman/collection/View.scala @@ -190,7 +190,16 @@ object View extends IterableFactory[View] { def iterator() = underlying.iterator().zip(other) override def knownSize = underlying.knownSize min other.knownSize } - + + /** A view that zips elements of the underlying collection with the elements + * of another collection or iterator, and then applies a function `f` to each pair. + */ + case class ZipWith[A, B, R](underlying: Iterable[A], other: Iterable[B], f: (A, B) => R) extends View[R] { + def iterator(): Iterator[R] = underlying.iterator().zipWith(other.iterator())(f) + override def knownSize: Int = underlying.knownSize min other.knownSize + } + + /** A view that appends an element to its elements */ case class Append[A](underlying: Iterable[A], elem: A) extends View[A] { def iterator(): Iterator[A] = Concat(underlying, View.Single(elem)).iterator()