Skip to content

Commit 71cf302

Browse files
committed
Add toMultimap to RxScala
1 parent 13bf771 commit 71cf302

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

language-adaptors/rxjava-scala/src/examples/scala/rx/lang/scala/examples/RxScalaDemo.scala

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,40 @@ class RxScalaDemo extends JUnitSuite {
865865
println(m.toBlockingObservable.single)
866866
}
867867

868+
@Test def toMultimapExample1(): Unit = {
869+
val o : Observable[String] = List("alice", "bob", "carol", "allen", "clarke").toObservable
870+
val keySelector = (s: String) => s.head
871+
val m = o.toMultimap(keySelector)
872+
println(m.toBlocking.single.mapValues(_.toList))
873+
}
874+
875+
@Test def toMultimapExample2(): Unit = {
876+
val o : Observable[String] = List("alice", "bob", "carol", "allen", "clarke").toObservable
877+
val keySelector = (s: String) => s.head
878+
val valueSelector = (s: String) => s.tail
879+
val m = o.toMultimap(keySelector, valueSelector)
880+
println(m.toBlocking.single.mapValues(_.toList))
881+
}
882+
883+
@Test def toMultimapExample3(): Unit = {
884+
val o : Observable[String] = List("alice", "bob", "carol", "allen", "clarke").toObservable
885+
val keySelector = (s: String) => s.head
886+
val valueSelector = (s: String) => s.tail
887+
val mapFactory = () => Map('d' -> List("oug"))
888+
val m = o.toMultimap(keySelector, valueSelector, mapFactory)
889+
println(m.toBlocking.single.mapValues(_.toList))
890+
}
891+
892+
@Test def toMultimapExample4(): Unit = {
893+
val o : Observable[String] = List("alice", "bob", "carol", "allen", "clarke").toObservable
894+
val keySelector = (s: String) => s.head
895+
val valueSelector = (s: String) => s.tail
896+
val mapFactory = () => Map('d' -> List("oug"))
897+
val valueFactor = (k: Char) => List[String]()
898+
val m = o.toMultimap(keySelector, valueSelector, mapFactory, valueFactor)
899+
println(m.toBlocking.single)
900+
}
901+
868902
@Test def containsExample(): Unit = {
869903
val o1 = List(1, 2, 3).toObservable.contains(2)
870904
assertTrue(o1.toBlockingObservable.single)

language-adaptors/rxjava-scala/src/main/scala/rx/lang/scala/Observable.scala

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3880,6 +3880,83 @@ trait Observable[+T]
38803880
def longCount: Observable[Long] = {
38813881
toScalaObservable[java.lang.Long](asJavaObservable.longCount()).map(_.longValue())
38823882
}
3883+
3884+
/**
3885+
* Returns an Observable that emits a single `Map` that contains an `Seq` of items emitted by the
3886+
* source Observable keyed by a specified keySelector` function.
3887+
*
3888+
* <img width="640" height="305" src="https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/toMultiMap.png">
3889+
*
3890+
* @param keySelector the function that extracts the key from the source items to be used as key in the HashMap
3891+
* @return an Observable that emits a single item: a `Map` that contains an `Seq` of items mapped from
3892+
* the source Observable
3893+
*/
3894+
def toMultimap[K](keySelector: T => K): Observable[Map[K, Seq[T]]] = {
3895+
val thisJava = asJavaObservable.asInstanceOf[rx.Observable[T]]
3896+
val o: rx.Observable[java.util.Map[K, java.util.Collection[T]]] = thisJava.toMultimap[K](keySelector)
3897+
toScalaObservable[java.util.Map[K, java.util.Collection[T]]](o).map(m => m.toMap.mapValues(_.toSeq))
3898+
}
3899+
3900+
/**
3901+
* Returns an Observable that emits a single `Map` that contains an `Seq` of values extracted by a
3902+
* specified `valueSelector` function from items emitted by the source Observable, keyed by a
3903+
* specified `keySelector` function.
3904+
*
3905+
* <img width="640" height="305" src="https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/toMultiMap.png">
3906+
*
3907+
* @param keySelector the function that extracts a key from the source items to be used as key in the HashMap
3908+
* @param valueSelector the function that extracts a value from the source items to be used as value in the HashMap
3909+
* @return an Observable that emits a single item: a `Map` that contains an `Seq` of items mapped from
3910+
* the source Observable
3911+
*/
3912+
def toMultimap[K, V](keySelector: T => K, valueSelector: T => V): Observable[Map[K, Seq[V]]] = {
3913+
val thisJava = asJavaObservable.asInstanceOf[rx.Observable[T]]
3914+
val o: rx.Observable[java.util.Map[K, java.util.Collection[V]]] = thisJava.toMultimap[K, V](keySelector, valueSelector)
3915+
toScalaObservable[java.util.Map[K, java.util.Collection[V]]](o).map(m => m.toMap.mapValues(_.toSeq))
3916+
}
3917+
3918+
/**
3919+
* Returns an Observable that emits a single `Map`, returned by a specified mapFactory` function, that
3920+
* contains an `Seq` of values, extracted by a specified `valueSelector` function from items
3921+
* emitted by the source Observable and keyed by the `keySelector` function.
3922+
*
3923+
* <img width="640" height="305" src="https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/toMultiMap.png">
3924+
*
3925+
* @param keySelector the function that extracts a key from the source items to be used as the key in the Map
3926+
* @param valueSelector the function that extracts a value from the source items to be used as the value in the Map
3927+
* @param mapFactory he function that returns a Map instance to be used
3928+
* @return an Observable that emits a single item: a `Map` that contains a `Seq` items mapped from the source
3929+
* Observable
3930+
*/
3931+
def toMultimap[K, V](keySelector: T => K, valueSelector: T => V, mapFactory: () => Map[K, Seq[V]]): Observable[Map[K, Seq[V]]] = {
3932+
val thisJava = asJavaObservable.asInstanceOf[rx.Observable[T]]
3933+
val o: rx.Observable[java.util.Map[K, java.util.Collection[V]]] = thisJava.toMultimap[K, V](keySelector, valueSelector)
3934+
toScalaObservable[java.util.Map[K, java.util.Collection[V]]](o).map(m => mapFactory() ++ m.toMap.mapValues(_.toSeq))
3935+
}
3936+
3937+
/**
3938+
* Returns an Observable that emits a single `Map`, returned by a specified `mapFactory` function, that
3939+
* contains a custom `Seq` of values, extracted by a specified `valueSelector` function from
3940+
* items emitted by the source Observable, and keyed by the `keySelector` function.
3941+
*
3942+
* <img width="640" height="305" src="https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/toMultiMap.png">
3943+
*
3944+
* @param keySelector the function that extracts a key from the source items to be used as the key in the Map
3945+
* @param valueSelector the function that extracts a value from the source items to be used as the value in the Map
3946+
* @param mapFactory the function that returns a Map instance to be used
3947+
* @param collectionFactory the function that returns a Collection instance for a particular key to be used in the Map
3948+
* @return an Observable that emits a single item: a `Map` that contains the `Seq` of mapped items from
3949+
* the source Observable
3950+
*/
3951+
def toMultimap[K, V](keySelector: T => K, valueSelector: T => V, mapFactory: () => Map[K, Seq[V]], collectionFactory: K => Seq[V]): Observable[Map[K, Seq[V]]] = {
3952+
val thisJava = asJavaObservable.asInstanceOf[rx.Observable[T]]
3953+
val o: rx.Observable[java.util.Map[K, java.util.Collection[V]]] = thisJava.toMultimap[K, V](keySelector, valueSelector)
3954+
toScalaObservable[java.util.Map[K, java.util.Collection[V]]](o).map {
3955+
m => mapFactory() ++ m.toMap.map {
3956+
case (k: K, v: java.util.Collection[V]) => (k, collectionFactory(k) ++ v)
3957+
}
3958+
}
3959+
}
38833960
}
38843961

38853962
/**

language-adaptors/rxjava-scala/src/test/scala/rx/lang/scala/CompletenessTest.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ class CompletenessTest extends JUnitSuite {
177177
"timer(Long, Long, TimeUnit)" -> "timer(Duration, Duration)",
178178
"timer(Long, Long, TimeUnit, Scheduler)" -> "timer(Duration, Duration, Scheduler)",
179179
"toList()" -> "toSeq",
180+
"toMultimap(Func1[_ >: T, _ <: K], Func1[_ >: T, _ <: V], Func0[_ <: Map[K, Collection[V]]])" -> "toMultimap(T => K, T => V, () => Map[K, Seq[V]])",
181+
"toMultimap(Func1[_ >: T, _ <: K], Func1[_ >: T, _ <: V], Func0[_ <: Map[K, Collection[V]]], Func1[_ >: K, _ <: Collection[V]])" -> "toMultimap(T => K, T => V, () => Map[K, Seq[V]], K => Seq[V])",
180182
"toSortedList()" -> "[Sorting is already done in Scala's collection library, use `.toSeq.map(_.sorted)`]",
181183
"toSortedList(Func2[_ >: T, _ >: T, Integer])" -> "[Sorting is already done in Scala's collection library, use `.toSeq.map(_.sortWith(f))`]",
182184
"window(Observable[U])" -> "window(=> Observable[Any])",

0 commit comments

Comments
 (0)