@@ -199,6 +199,8 @@ class Observable[+T](val asJava: rx.Observable[_ <: T])
199
199
def zip [U ](that : Observable [U ]): Observable [(T , U )] = {
200
200
Observable [(T , U )](JObservable .zip[T , U , (T , U )](this .asJava, that.asJava, (t : T , u : U ) => (t, u)))
201
201
}
202
+
203
+ // public static <R> Observable<R> zip(Observable<? extends Observable<?>> ws, final FuncN<? extends R> zipFunction) {
202
204
203
205
/**
204
206
* Zips this Observable with its indices.
@@ -1068,6 +1070,21 @@ class Observable[+T](val asJava: rx.Observable[_ <: T])
1068
1070
Observable [T ](asJava.skip(n))
1069
1071
}
1070
1072
1073
+ /**
1074
+ * Returns an Observable that bypasses all items from the source Observable as long as the specified
1075
+ * condition holds true. Emits all further source items as soon as the condition becomes false.
1076
+ * <p>
1077
+ * <img width="640" src="https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/skipWhile.png">
1078
+ *
1079
+ * @param predicate
1080
+ * A function to test each item emitted from the source Observable for a condition.
1081
+ * @return an Observable that emits all items from the source Observable as soon as the condition
1082
+ * becomes false.
1083
+ */
1084
+ def dropWhile (predicate : T => Boolean ): Observable [T ] = {
1085
+ Observable [T ](asJava.skipWhile(predicate))
1086
+ }
1087
+
1071
1088
/**
1072
1089
* Returns an Observable that emits only the first <code>num</code> items emitted by the source
1073
1090
* Observable.
@@ -1436,6 +1453,56 @@ class Observable[+T](val asJava: rx.Observable[_ <: T])
1436
1453
def product [U >: T ](implicit num : Numeric [U ]): Observable [U ] = {
1437
1454
fold(num.one)(num.times)
1438
1455
}
1456
+
1457
+ /**
1458
+ * TODO doc&test
1459
+ */
1460
+ def firstOrElse [U >: T ](default : => U ): Observable [U ] = {
1461
+ this .materialize.take(1 ).map((n : Notification [T ]) => {
1462
+ if (n.getKind() == rx.Notification .Kind .OnNext )
1463
+ n.getValue
1464
+ else
1465
+ default
1466
+ })
1467
+ }
1468
+
1469
+ // TODO which of these two find variants do we want?
1470
+
1471
+ /**
1472
+ * Finds the first element of the list satisfying a predicate, if any.
1473
+ * @param p
1474
+ * the predicate used to test elements.
1475
+ * @return an Observable emitting an Option containing the first element in the source
1476
+ * Observable that satisfies p, or None if none exists or onError was called.
1477
+ */
1478
+ def find (p : T => Boolean ): Observable [Option [T ]] = {
1479
+ this .filter(p).materialize.take(1 ).map((n : Notification [T ]) => {
1480
+ if (n.getKind() == rx.Notification .Kind .OnNext )
1481
+ Some (n.getValue())
1482
+ else
1483
+ None
1484
+ })
1485
+ }
1486
+
1487
+ /**
1488
+ * Finds the first element of the list satisfying a predicate, if any.
1489
+ * @param p
1490
+ * the predicate used to test elements.
1491
+ * @return an Observable emitting an Option containing the first element in the source
1492
+ * Observable that satisfies p, or None if none exists.
1493
+ */
1494
+ private def findWhichTransmitsError (p : T => Boolean ): Observable [Option [T ]] = {
1495
+ val o : Observable [Notification [Option [T ]]] =
1496
+ this .filter(p).materialize.take(1 ).map((n : Notification [T ]) => {
1497
+ if (n.getKind() == rx.Notification .Kind .OnCompleted )
1498
+ Notification (None )
1499
+ else if (n.getKind() == rx.Notification .Kind .OnNext )
1500
+ Notification (Some (n.getValue()))
1501
+ else
1502
+ Notification (n.getThrowable())
1503
+ })
1504
+ o.dematerialize
1505
+ }
1439
1506
1440
1507
/**
1441
1508
* Converts an Observable into a {@link BlockingObservable} (an Observable with blocking
@@ -1461,6 +1528,7 @@ object Observable {
1461
1528
import rx .{Observable => JObservable }
1462
1529
import rx .lang .scala .{Notification , Subscription , Scheduler , Observer }
1463
1530
import rx .lang .scala .util ._
1531
+ import rx .util .functions ._
1464
1532
import rx .lang .scala .ImplicitFunctionConversions ._
1465
1533
1466
1534
private [scala]
@@ -1676,19 +1744,19 @@ object Observable {
1676
1744
def never : Observable [Nothing ] = {
1677
1745
Observable [Nothing ](JObservable .never())
1678
1746
}
1679
-
1747
+
1680
1748
/*
1681
1749
def apply[T](f: Future[T]): Observable[T] = {
1682
1750
??? // TODO convert Scala Future to Java Future
1683
1751
}
1684
1752
*/
1685
-
1753
+
1686
1754
/*
1687
1755
def apply[T](f: Future[T], scheduler: Scheduler): Observable[T] = {
1688
1756
??? // TODO convert Scala Future to Java Future
1689
1757
}
1690
1758
*/
1691
-
1759
+
1692
1760
/*
1693
1761
def apply[T](f: Future[T], duration: Duration): Observable[T] = {
1694
1762
??? // TODO convert Scala Future to Java Future
@@ -1700,7 +1768,7 @@ object Observable {
1700
1768
* each time an event is received from one of the source observables, where the aggregation is defined by the given function.
1701
1769
* <p>
1702
1770
* <img width="640" src="https://github.com/Netflix/RxJava/wiki/images/rx-operators/combineLatest.png">
1703
- *
1771
+ *
1704
1772
* @param o1
1705
1773
* The first source observable.
1706
1774
* @param o2
@@ -1712,14 +1780,57 @@ object Observable {
1712
1780
// public static <T1, T2, R> Observable<R> combineLatest(Observable<? extends T1> o1, Observable<? extends T2> o2, Func2<? super T1, ? super T2, ? extends R> combineFunction)
1713
1781
// TODO do we want this as an instance method?
1714
1782
// TODO then decide about combineLatest with > 2 Observables
1715
-
1783
+
1716
1784
// TODO what about these two?
1717
1785
// public static <R> Observable<R> zip(Observable<? extends Observable<?>> ws, final FuncN<? extends R> zipFunction)
1718
1786
// public static <R> Observable<R> zip(Collection<? extends Observable<?>> ws, FuncN<? extends R> zipFunction)
1719
1787
1788
+ /**
1789
+ * Given a Seq of N observables, returns an observable that emits Seqs of N elements each.
1790
+ * The first emitted Seq will contain the first element of each source observable,
1791
+ * the second Seq the second element of each source observable, and so on.
1792
+ *
1793
+ * @param observables
1794
+ * A Seq of source Observables
1795
+ * @return an Observable that emits the zipped Seqs
1796
+ */
1797
+ def zip [T ](observables : Seq [Observable [T ]]): Observable [Seq [T ]] = {
1798
+ val f : FuncN [Seq [T ]] = (args : Seq [java.lang.Object ]) => {
1799
+ val asSeq : Seq [Object ] = args.toSeq
1800
+ asSeq.asInstanceOf [Seq [T ]]
1801
+ }
1802
+ val list = observables.map(_.asJava).asJava
1803
+ val o = rx.Observable .zip(list, f)
1804
+ Observable [Seq [T ]](o)
1805
+ }
1806
+
1807
+ /**
1808
+ * Given an Observable emitting N source observables, returns an observable that emits Seqs of N elements each.
1809
+ * The first emitted Seq will contain the first element of each source observable,
1810
+ * the second Seq the second element of each source observable, and so on.
1811
+ *
1812
+ * @param observables
1813
+ * An Observable emitting N source Observables
1814
+ * @return an Observable that emits the zipped Seqs
1815
+ */
1816
+ def zip [T ](observables : Observable [Observable [T ]]): Observable [Seq [T ]] = {
1817
+ val f : FuncN [Seq [T ]] = (args : Seq [java.lang.Object ]) => {
1818
+ val asSeq : Seq [Object ] = args.toSeq
1819
+ asSeq.asInstanceOf [Seq [T ]]
1820
+ }
1821
+ val list = observables.map(_.asJava).asJava
1822
+ val o = rx.Observable .zip(list, f)
1823
+ Observable [Seq [T ]](o)
1824
+ }
1825
+
1720
1826
def interval (duration : Duration ): Observable [Long ] = {
1721
1827
(new Observable [java.lang.Long ](JObservable .interval(duration.length, duration.unit))).map(_.longValue())
1722
1828
}
1829
+
1830
+ def interval (duration : Duration , scheduler : Scheduler ): Observable [Long ] = {
1831
+ (new Observable [java.lang.Long ](JObservable .interval(duration.length, duration.unit, scheduler))).map(_.longValue())
1832
+ }
1833
+
1723
1834
}
1724
1835
1725
1836
// Cannot yet have inner class because of this error message:
@@ -1776,6 +1887,14 @@ class UnitTestSuite extends JUnitSuite {
1776
1887
assertEquals(demat.toBlockingObservable.toIterable.toList, List (1 , 2 , 3 ))
1777
1888
}
1778
1889
1890
+ @ Test def testFind () {
1891
+ assertEquals(Some (3 ), Observable (1 , 3 , 5 ).find(_ >= 2 ).toBlockingObservable.single)
1892
+ assertEquals(Some (1 ), Observable (1 , 3 , 5 ).find(_ => true ).toBlockingObservable.single)
1893
+ assertEquals(None , Observable (1 , 3 , 5 ).find(_ > 10 ).toBlockingObservable.single)
1894
+ assertEquals(None , Observable (new Exception ()).find((i : Int ) => i > 10 ).toBlockingObservable.single)
1895
+ assertEquals(None , Observable ().find((i : Int ) => i > 10 ).toBlockingObservable.single)
1896
+ }
1897
+
1779
1898
@ Test def testTest () = {
1780
1899
val a : Observable [Int ] = Observable ()
1781
1900
assertEquals(4 , Observable (1 , 2 , 3 , 4 ).toBlockingObservable.toIterable.last)
0 commit comments