diff --git a/docs/Problem-Solving-Examples-in-RxJava.md b/docs/Problem-Solving-Examples-in-RxJava.md index 1b41c2a122..6b848ae693 100644 --- a/docs/Problem-Solving-Examples-in-RxJava.md +++ b/docs/Problem-Solving-Examples-in-RxJava.md @@ -1,4 +1,4 @@ -This page will present some elementary RxJava puzzles and walk through some solutions (using the Groovy language implementation of RxJava) as a way of introducing you to some of the RxJava operators. +This page will present some elementary RxJava puzzles and walk through some solutions as a way of introducing you to some of the RxJava operators. # Project Euler problem #1 @@ -7,10 +7,22 @@ There used to be a site called "Project Euler" that presented a series of mathem > If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000. There are several ways we could go about this with RxJava. We might, for instance, begin by going through all of the natural numbers below 1000 with [`range`](Creating-Observables#range) and then [`filter`](Filtering-Observables#filter) out those that are not a multiple either of 3 or of 5: +### Java +```java +Observable threesAndFives = Observable.range(1, 999).filter(e -> e % 3 == 0 || e % 5 == 0); +``` +### Groovy ````groovy def threesAndFives = Observable.range(1,999).filter({ !((it % 3) && (it % 5)) }); ```` Or, we could generate two Observable sequences, one containing the multiples of three and the other containing the multiples of five (by [`map`](https://github.com/Netflix/RxJava/wiki/Transforming-Observables#map)ping each value onto its appropriate multiple), making sure to only generating new multiples while they are less than 1000 (the [`takeWhile`](Conditional-and-Boolean-Operators#takewhile-and-takewhilewithindex) operator will help here), and then [`merge`](Combining-Observables#merge) these sets: +### Java +```java +Observable threes = Observable.range(1, 999).map(e -> e * 3).takeWhile(e -> e < 1000); +Observable fives = Observable.range(1, 999).map(e -> e * 5).takeWhile(e -> e < 1000); +Observable threesAndFives = Observable.merge(threes, fives).distinct(); +``` +### Groovy ````groovy def threes = Observable.range(1,999).map({it*3}).takeWhile({it<1000}); def fives = Observable.range(1,999).map({it*5}).takeWhile({it<1000}); @@ -21,6 +33,11 @@ Don't forget the [`distinct`](Filtering-Observables#distinct) operator here, oth Next, we want to sum up the numbers in the resulting sequence. If you have installed the optional `rxjava-math` module, this is elementary: just use an operator like [`sumInteger` or `sumLong`](Mathematical-and-Aggregate-Operators#suminteger-sumlong-sumfloat-and-sumdouble) on the `threesAndFives` Observable. But what if you don't have this module? How could you use standard RxJava operators to sum up a sequence and emit that sum? There are a number of operators that reduce a sequence emitted by a source Observable to a single value emitted by the resulting Observable. Most of the ones that are not in the `rxjava-math` module emit boolean evaluations of the sequence; we want something that can emit a number. The [`reduce`](Mathematical-and-Aggregate-Operators#reduce) operator will do the job: +### Java +```java +Single summer = threesAndFives.reduce(0, (a, b) -> a + b); +``` +### Groovy ````groovy def summer = threesAndFives.reduce(0, { a, b -> a+b }); ```` @@ -38,6 +55,12 @@ Here is how `reduce` gets the job done. It starts with 0 as a seed. Then, with e Finally, we want to see the result. This means we must [subscribe](Observable#onnext-oncompleted-and-onerror) to the Observable we have constructed: + +### Java +```java +summer.subscribe(System.out::print); +``` +### Groovy ````groovy summer.subscribe({println(it);}); ```` @@ -47,11 +70,24 @@ summer.subscribe({println(it);}); How could you create an Observable that emits [the Fibonacci sequence](http://en.wikipedia.org/wiki/Fibonacci_number)? The most direct way would be to use the [`create`](Creating-Observables#wiki-create) operator to make an Observable "from scratch," and then use a traditional loop within the closure you pass to that operator to generate the sequence. Something like this: +### Java +```java +Observable fibonacci = Observable.create(emitter -> { + int f1 = 0, f2 = 1, f = 1; + while (!emitter.isDisposed()) { + emitter.onNext(f); + f = f1 + f2; + f1 = f2; + f2 = f; + } +}); +``` +### Groovy ````groovy -def fibonacci = Observable.create({ observer -> - def f1=0; f2=1, f=1; - while(!observer.isUnsubscribed() { - observer.onNext(f); +def fibonacci = Observable.create({ emitter -> + def f1=0, f2=1, f=1; + while(!emitter.isDisposed()) { + emitter.onNext(f); f = f1+f2; f1 = f2; f2 = f; @@ -61,7 +97,16 @@ def fibonacci = Observable.create({ observer -> But this is a little too much like ordinary linear programming. Is there some way we can instead create this sequence by composing together existing Observable operators? Here's an option that does this: -```` +### Java +```java +Observable fibonacci = + Observable.fromArray(0) + .repeat() + .scan(new int[]{0, 1}, (a, b) -> new int[]{a[1], a[0] + a[1]}) + .map(a -> a[1]); +``` +### Groovy +````groovy def fibonacci = Observable.from(0).repeat().scan([0,1], { a,b -> [a[1], a[0]+a[1]] }).map({it[1]}); ```` It's a little [janky](http://www.urbandictionary.com/define.php?term=janky). Let's walk through it: @@ -73,6 +118,11 @@ This has the effect of emitting the following sequence of items: `[0,1], [1,1], The second item in this array describes the Fibonacci sequence. We can use `map` to reduce the sequence to just that item. To print out a portion of this sequence (using either method), you would use code like the following: +### Java +```java +fibonacci.take(15).subscribe(System.out::println); +``` +### Groovy ````groovy fibonnaci.take(15).subscribe({println(it)})]; ````