Skip to content

Commit ef3ff56

Browse files
Merge pull request #159 from mairbek/lastOrDefault
Implemented LastOrDefault Operator
2 parents f0e8ca3 + 5ef9e4a commit ef3ff56

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

language-adaptors/rxjava-groovy/src/test/groovy/rx/lang/groovy/ObservableTests.groovy

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,18 @@ def class ObservableTests {
233233
}
234234
}
235235

236+
@Test
237+
public void testLastOrDefault() {
238+
def val = Observable.toObservable("one", "two").lastOrDefault("default", { x -> x.length() == 3})
239+
assertEquals("two", val)
240+
}
241+
242+
@Test
243+
public void testLastOrDefault2() {
244+
def val = Observable.toObservable("one", "two").lastOrDefault("default", { x -> x.length() > 3})
245+
assertEquals("default", val)
246+
}
247+
236248
def class AsyncObservable implements Func1<Observer<Integer>, Subscription> {
237249

238250
public Subscription call(final Observer<Integer> observer) {

rxjava-core/src/main/java/rx/Observable.java

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,61 @@ public static <T> Observable<T> last(final Observable<T> that) {
685685
return _create(OperationLast.last(that));
686686
}
687687

688+
/**
689+
* Returns the last element of an observable sequence, or a default value if no value is found.
690+
* @param source the source observable.
691+
* @param defaultValue a default value that would be returned if observable is empty.
692+
* @param <T> the type of source.
693+
* @return the last element of an observable sequence that matches the predicate, or a default value if no value is found.
694+
*/
695+
public static <T> T lastOrDefault(Observable<T> source, T defaultValue) {
696+
boolean found = false;
697+
T result = null;
698+
699+
for (T value : source.toIterable()) {
700+
found = true;
701+
result = value;
702+
}
703+
704+
if (!found) {
705+
return defaultValue;
706+
}
707+
708+
return result;
709+
}
710+
711+
/**
712+
* Returns the last element of an observable sequence that matches the predicate, or a default value if no value is found.
713+
* @param source the source observable.
714+
* @param defaultValue a default value that would be returned if observable is empty.
715+
* @param predicate a predicate function to evaluate for elements in the sequence.
716+
* @param <T> the type of source.
717+
* @return the last element of an observable sequence that matches the predicate, or a default value if no value is found.
718+
*/
719+
public static <T> T lastOrDefault(Observable<T> source, T defaultValue, Func1<T, Boolean> predicate) {
720+
return lastOrDefault(source.filter(predicate), defaultValue);
721+
}
722+
723+
/**
724+
* Returns the last element of an observable sequence that matches the predicate, or a default value if no value is found.
725+
* @param source the source observable.
726+
* @param defaultValue a default value that would be returned if observable is empty.
727+
* @param predicate a predicate function to evaluate for elements in the sequence.
728+
* @param <T> the type of source.
729+
* @return the last element of an observable sequence that matches the predicate, or a default value if no value is found.
730+
*/
731+
public static <T> T lastOrDefault(Observable<T> source, T defaultValue, Object predicate){
732+
@SuppressWarnings("rawtypes")
733+
final FuncN _f = Functions.from(predicate);
734+
735+
return lastOrDefault(source, defaultValue, new Func1<T, Boolean>() {
736+
@Override
737+
public Boolean call(T args) {
738+
return (Boolean) _f.call(args);
739+
}
740+
});
741+
}
742+
688743
/**
689744
* Applies a function of your choosing to every notification emitted by an Observable, and returns
690745
* this transformation as a new Observable sequence.
@@ -2030,6 +2085,38 @@ public Observable<T> last() {
20302085
return last(this);
20312086
}
20322087

2088+
/**
2089+
* Returns the last element, or a default value if no value is found.
2090+
*
2091+
* @param defaultValue a default value that would be returned if observable is empty.
2092+
* @return the last element of an observable sequence that matches the predicate, or a default value if no value is found.
2093+
*/
2094+
public T lastOrDefault(T defaultValue) {
2095+
return lastOrDefault(this, defaultValue);
2096+
}
2097+
2098+
/**
2099+
* Returns the last element that matches the predicate, or a default value if no value is found.
2100+
*
2101+
* @param defaultValue a default value that would be returned if observable is empty.
2102+
* @param predicate a predicate function to evaluate for elements in the sequence.
2103+
* @return the last element of an observable sequence that matches the predicate, or a default value if no value is found.
2104+
*/
2105+
public T lastOrDefault(T defaultValue, Func1<T, Boolean> predicate) {
2106+
return lastOrDefault(this, defaultValue, predicate);
2107+
}
2108+
2109+
/**
2110+
* Returns the last element that matches the predicate, or a default value if no value is found.
2111+
*
2112+
* @param defaultValue a default value that would be returned if observable is empty.
2113+
* @param predicate a predicate function to evaluate for elements in the sequence.
2114+
* @return the last element of an observable sequence that matches the predicate, or a default value if no value is found.
2115+
*/
2116+
public T lastOrDefault(T defaultValue, Object predicate) {
2117+
return lastOrDefault(this, defaultValue, predicate);
2118+
}
2119+
20332120
/**
20342121
* Applies a function of your choosing to every item emitted by an Observable, and returns this
20352122
* transformation as a new Observable sequence.
@@ -2743,6 +2830,55 @@ public Subscription call(Observer<String> observer) {
27432830

27442831
}
27452832

2833+
@Test
2834+
public void testLastOrDefault1() {
2835+
Observable<String> observable = toObservable("one", "two", "three");
2836+
assertEquals("three", observable.lastOrDefault("default"));
2837+
}
2838+
2839+
@Test
2840+
public void testLastOrDefault2() {
2841+
Observable<String> observable = toObservable();
2842+
assertEquals("default", observable.lastOrDefault("default"));
2843+
}
2844+
2845+
@Test
2846+
public void testLastOrDefault() {
2847+
Observable<Integer> observable = toObservable(1, 0, -1);
2848+
int last = observable.lastOrDefault(-100, new Func1<Integer, Boolean>() {
2849+
@Override
2850+
public Boolean call(Integer args) {
2851+
return args >= 0;
2852+
}
2853+
});
2854+
assertEquals(0, last);
2855+
}
2856+
2857+
@Test
2858+
public void testLastOrDefaultWrongPredicate() {
2859+
Observable<Integer> observable = toObservable(-1, -2, -3);
2860+
int last = observable.lastOrDefault(0, new Func1<Integer, Boolean>() {
2861+
@Override
2862+
public Boolean call(Integer args) {
2863+
return args >= 0;
2864+
}
2865+
});
2866+
assertEquals(0, last);
2867+
}
2868+
2869+
@Test
2870+
public void testLastOrDefaultWithPredicate() {
2871+
Observable<Integer> observable = toObservable(1, 0, -1);
2872+
int last = observable.lastOrDefault(0, new Func1<Integer, Boolean>() {
2873+
@Override
2874+
public Boolean call(Integer args) {
2875+
return args < 0;
2876+
}
2877+
});
2878+
2879+
assertEquals(-1, last);
2880+
}
2881+
27462882
private static class TestException extends RuntimeException {
27472883

27482884
}

0 commit comments

Comments
 (0)