RxFunctions

Additional

Language
Java
Version
1.0.0 (Mar 2, 2016)
Created
Mar 2, 2016
Updated
Jan 21, 2017 (Retired)
Owner
Paco (pakoito)
Contributors
Ravindra Kumar (ravidsrk)
Paco (pakoito)
2
Activity
Badge
Generate
Download
Source code

RxFunctions

RxFunctions is a library to smooth RxJava usage by functionally composing functions.

For the RxJava 2.X version please go to RxFunctions2.

Rationale

Oftentimes you want to filter an Observable based off several criteria, i.e. get your users above a certain age that also live in a certain city; a string that should not be null or empty; or two objects being equal and both higher than 0.

Other times you have to chain several map operations in a row, like converting your network data from string to dto, and from dto to a viewmodel.

Where you could write 2-9 operations every time that chain surfaces, instead you can compose them a create a new, single, more meaningful function.

Usage

General Functions

These functions work for any type and situation.

Same

It allows you to chain Func1<T, T> that have the same input and output types, like two Func1<String String>, or six Func1<Integer, Integer>.

The end result is a Func1<T, T> that applies all of them sequentially and returns the result of the last one.

Chain

Chain allows composition of functions that change type, but maintain a logical sequence. This is useful in map operations, like transforming a string into an object Func1<String, User> and then retrieving one of the fields Func1<User, List<Locations>> to finally compose our target class Func1<List<Locations>, LocationDirectory>.

The end result is a Func1<T, R> that applies all of them sequentially and returns a function that takes a parameter from the first one and returns the result of the last one.

Combine

Combine allows you to add up small operations into bigger ones. This case is common for object mutation, where you take one type parameter UserDto and have 4 functions Func1<UserDto, String> to transform its fields into strings used by a constructor function Func4<String, String, String, String, UserViewModel>.

The end result is a function that applies several Func1<T, U> Func1<T, V> Func1<T, W> parameters to the final aggregation function whose arity is one for each Func3<U, V, W, R>

Reduce

Reduce is the most complicated to understand, as it allows for incremental composition. You provide:

  • An initial value of type R

  • An aggregation function of type Func2<R, R, R> that takes the previous state, a new value obtained from the function being evaluated, and returns the new state

  • Any number of Func1<T, R>.

Each function will be applied individually to the initial value by using the aggregation function until the last one gives the final result.

One example is the composition and() described below. It represents an operation of type Func1<T, Boolean>, which takes an initial value of true, a set of functions returning booleans, and applies aggregation by doing && between them.

The end result is a function Func1<T, R> that has one input object, and returns the result of the internal aggregation.

Boolean functions

The next composers work only for Func1<T, Boolean>.

Not

Not negates the result of a Func1<T, Boolean> to allow the creation of opposite functions. The most common case is testing if a filter does not fit a function defined previously.

And

And aggregates the result of any number of Func1<T, Boolean> by means of &&. This helps composing more fine-grained filters into a single operation.

Or

And aggregates the result of any number of Func1<T, Boolean> by means of ||. This helps composing more fine-grained filters into a single operation.

Examples

Func1<Integer, Integer> INCREMENT = num -> num + 1;
Func1<Integer, Integer> SUM_FOUR =
                        RxFunctions.<Integer>same(INCREMENT, INCREMENT, INCREMENT, INCREMENT).call(0) // returns 4

Func1<Integer, String> TO_STRING = num -> num + "";
Func1<Integer, String> TO_INT = string -> Integer.parseInt(string);
Func1<Integer, String> ROUND TRIPS =
                        RxFunctions.chain(TO_STRING, TO_INT, TO_STRING, TO_INT, TO_STRING).call(5); // returns "5"

Or more complex cases:

Func1<User, Boolean> BEST_USERS_FILTER =
                            RxFunctions.and(NOT_NULL,
                                            RxFunctions.not(IS_DEACTIVATED)
                                            RxFunctions.or(HAS_MANY_PURCHASES,
                                                            IS_HIGH_INCOME));
List<User> bestUsersList = getUserList().filter(BEST_USERS_FILTER).toList().toBlocking().first();

Distribution

Add as a dependency to your build.gradle

repositories {
    ...
    maven { url "https://jitpack.io" }
    ...
}
    
dependencies {
    ...
    compile 'com.github.pakoito:RxFunctions:1.0.0'
    ...
}

or to your pom.xml

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.pakoito</groupId>
    <artifactId>RxFunctions</artifactId>
    <version>1.0.0</version>
</dependency>

License

Copyright (c) pakoito 2016

The Apache Software License, Version 2.0

See LICENSE.md