From 46af17c33cf105f8e99ca75f0917dd95c81e568c Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 10 Nov 2009 16:39:16 +0000 Subject: Zipped for Tuple2&Tuple3 --- src/library/scala/Tuple2.scala | 19 ++++++- src/library/scala/Tuple3.scala | 112 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 9835e8505d..8a08552149 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -29,12 +29,27 @@ case class Tuple2[+T1, +T2](_1:T1, _2:T2) extends Product2[T1, T2] { /** Swap the elements of the tuple */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) +// TODO: probably loosen zip and zipped from <:< to <%< + + def zip[Repr1, El1, El2, To](implicit w1: T1 <:< TraversableLike[El1, Repr1], + w2: T2 <:< Iterable[El2], + cbf1: CanBuildFrom[Repr1, (El1, El2), To]): To = { + val coll1: TraversableLike[El1, Repr1] = _1 + val coll2: Iterable[El2] = _2 + val b1 = cbf1(coll1.repr) + val elems2 = coll2.iterator + + for(el1 <- coll1) + if(elems2.hasNext) + b1 += ((el1, elems2.next)) + + b1.result + } + def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 <:< TraversableLike[El1, Repr1], w2: T2 <:< IterableLike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] = new Zipped[Repr1, El1, Repr2, El2](_1, _2) class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TraversableLike[El1, Repr1], coll2: IterableLike[El2, Repr2]) { // coll2: IterableLike for filter - def it: (Repr1, Repr2) = (coll1.repr, coll2.repr) // TODO: do we want this? what should its name be? - def map[B, To](f: (El1, El2) => B)(implicit cbf: CanBuildFrom[Repr1, B, To]): To = { val b = cbf(coll1.repr) val elems2 = coll2.iterator diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index 5a12a9eebd..42418ecdd5 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -12,6 +12,8 @@ package scala +import scala.collection.{TraversableLike, Traversable, IterableLike} +import scala.collection.generic.CanBuildFrom /** Tuple3 is the canonical representation of a @see Product3 @@ -22,4 +24,114 @@ case class Tuple3[+T1, +T2, +T3](_1:T1,_2:T2,_3:T3) { override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")" +// TODO: probably loosen zip and zipped from <:< to <%< + + def zip[Repr1, El1, El2, El3, To](implicit w1: T1 <:< TraversableLike[El1, Repr1], + w2: T2 <:< Iterable[El2], + w3: T3 <:< Iterable[El3], + cbf1: CanBuildFrom[Repr1, (El1, El2, El3), To]): To = { + val coll1: TraversableLike[El1, Repr1] = _1 + val coll2: Iterable[El2] = _2 + val coll3: Iterable[El3] = _3 + val b1 = cbf1(coll1.repr) + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for(el1 <- coll1) + if(elems2.hasNext && elems3.hasNext) + b1 += ((el1, elems2.next, elems3.next)) + + b1.result + } + + def zipped[Repr1, El1, Repr2, El2, Repr3, El3](implicit w1: T1 <:< TraversableLike[El1, Repr1], + w2: T2 <:< IterableLike[El2, Repr2], + w3: T3 <:< IterableLike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3] + = new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3) + + class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TraversableLike[El1, Repr1], + coll2: IterableLike[El2, Repr2], + coll3: IterableLike[El3, Repr3]) { + def map[B, To](f: (El1, El2, El3) => B)(implicit cbf: CanBuildFrom[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for(el1 <- coll1) + if(elems2.hasNext && elems3.hasNext) + b += f(el1, elems2.next, elems3.next) + + b.result + } + + def flatMap[B, To](f: (El1, El2, El3) => Traversable[B])(implicit cbf: CanBuildFrom[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for(el1 <- coll1) + if(elems2.hasNext && elems3.hasNext) + b ++= f(el1, elems2.next, elems3.next) + + b.result + } + + def filter[To1, To2, To3](f: (El1, El2, El3) => Boolean)( + implicit cbf1: CanBuildFrom[Repr1, El1, To1], + cbf2: CanBuildFrom[Repr2, El2, To2], + cbf3: CanBuildFrom[Repr3, El3, To3]): (To1, To2, To3) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val b3 = cbf3(coll3.repr) + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for(el1 <- coll1) { + if(elems2.hasNext && elems3.hasNext) { + val el2 = elems2.next + val el3 = elems3.next + if(f(el1, el2, el3)) { + b1 += el1 + b2 += el2 + b3 += el3 + } + } + } + + (b1.result, b2.result, b3.result) + } + + def exists(f: (El1, El2, El3) => Boolean): Boolean = { + var acc = false + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for(el1 <- coll1) + if(!acc && elems2.hasNext && elems3.hasNext) + acc = f(el1, elems2.next, elems3.next) + + acc + } + + def forall(f: (El1, El2, El3) => Boolean): Boolean = { + var acc = true + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for(el1 <- coll1) + if(acc && elems2.hasNext && elems3.hasNext) + acc = f(el1, elems2.next, elems3.next) + + acc + } + + def foreach[U](f: (El1, El2, El3) => U): Unit = { + val elems2 = coll2.iterator + val elems3 = coll3.iterator + + for(el1 <- coll1) + if(elems2.hasNext && elems3.hasNext) + f(el1, elems2.next, elems3.next) + } + } } -- cgit v1.2.3