package com.tek271.funj;
import com.google.common.annotations.Beta;
import com.google.common.collect.Lists;
import java.util.List;
import static com.tek271.funj.CollectionTools.isEmpty;
@Beta
public class Reducer {
/**
* interface to be implemented by reduce functions
* @param <T> type of value to reduce.
*/
public static interface ReduceFunction<T> {
T reduceValue(T buffer, T value);
}
/**
* Left reduce the given iterable into a single value using the given reduceFunction
* @param iterable values to reduce starting at the first item
* @param reduceFunction the function to apply on each item
* @param initialValue the start value for the reduction
* @param <T> Type of values in iterable
* @return the reduced value
*/
public static <T> T reduce(Iterable<T> iterable,
ReduceFunction<T> reduceFunction,
T initialValue) {
if (isEmpty(iterable)) return initialValue;
T r = initialValue;
for (T i: iterable) {
r = reduceFunction.reduceValue(r, i);
}
return r;
}
/**
* Right reduce the given iterable into a single value using the given reduceFunction
* @param iterable values to reduce starting at the last item
* @param reduceFunction the function to apply on each item
* @param initialValue the start value for the reduction
* @param <T> Type of values in iterable
* @return the reduced value
*/
public static <T> T reduceRight(Iterable<T> iterable,
ReduceFunction<T> reduceFunction,
T initialValue) {
if (isEmpty(iterable)) return initialValue;
List<T> list = Lists.reverse(Lists.newLinkedList(iterable));
T r = initialValue;
for (T i:list) {
r = reduceFunction.reduceValue(r, i);
}
return r;
}
}