package ilarkesto.fp;
import ilarkesto.base.Tuple;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Static methods for functional programming.
*
*/
public abstract class FP {
public static <I, K, V> Map<K, V> map(Collection<I> elements, Function<I, Tuple<K, V>> mapFunction) {
Map<K, V> ret = new HashMap<K, V>();
for (I e : elements) {
Tuple<K, V> keyValue = mapFunction.eval(e);
ret.put(keyValue.getA(), keyValue.getB());
}
return ret;
}
/**
* Executes a function on each element in a list. The function results are returned in a list.
*
* @param <E> The element type.
* @param elements Elements to execute the function on.
* @param mapFunction The function to execute on each element.
* @return The function results.
*/
public static <I, O> List<O> foreach(Collection<I> elements, Function<I, O> mapFunction) {
List<O> result = new ArrayList<O>(elements.size());
for (I e : elements) {
result.add(mapFunction.eval(e));
}
return result;
}
/**
* Executes a function on each element in a list.
*
* @param <E> The element type.
* @param elements Elements to execute the function on.
* @param function The function to execute on each element.
*/
public static <E> void foreachVoid(Collection<E> elements, Function<E, ?> function) {
for (E e : elements) {
function.eval(e);
}
}
/**
* Groups elements from a collection by a group function.
*
* @param <G> The grouping object type. (Used as key in the result map).
* @param <E> The element type.
* @param elements The elements to group.
* @param groupFunction The function used to group elements
* @return
*/
public static <G, E> Map<G, List<E>> group(Collection<E> elements, Function<E, G> groupFunction) {
Map<G, List<E>> result = new HashMap<G, List<E>>();
for (E e : elements) {
G key = groupFunction.eval(e);
List<E> bucket = result.get(key);
if (bucket == null) {
bucket = new ArrayList<E>();
result.put(key, bucket);
}
bucket.add(e);
}
return result;
}
public static <T> Predicate<T> and(Predicate<T>... predicates) {
return new And<T>(predicates);
}
/**
* Filters a collection of elements by a predicate and returns a list.
*
* @param <T> The type of the elements.
* @param predicate The filter predicate.
* @param list The collection of elements.
*/
public static <T> List<T> filterList(Predicate<T> predicate, Collection<T> list) {
List<T> result = new ArrayList<T>();
for (T element : list) {
if (predicate.test(element)) result.add(element);
}
return result;
}
/**
* Filters a collection of elements by a predicate and returns a set.
*
* @param <T> The type of the elements.
* @param predicate The filter predicate.
* @param list The collection of elements.
*/
public static <T> Set<T> filterSet(Predicate<T> predicate, Collection<T> list) {
Set<T> result = new HashSet<T>();
for (T element : list) {
if (predicate.test(element)) result.add(element);
}
return result;
}
/**
* Gets specified values from a map. Returns a list with the values for which the keys are given.
*
* @param <K> Type of the keys.
* @param <V> Type of the values.
* @param keys The keys for which to return the values.
* @param map The map with the values to return.
*/
public static <K, V> List<V> values(Collection<K> keys, Map<K, V> map) {
List<V> result = new ArrayList<V>();
for (K key : keys)
result.add(map.get(key));
return result;
}
// --- functions / predicates ---
public static final Function<File, String> FILE_PATH = new Function<File, String>() {
@Override
public String eval(File e) {
return e.getPath();
}
};
public static List<String> filePaths(Collection<File> files) {
return foreach(files, FILE_PATH);
}
public static final Predicate<File> FILE_EXISTS = new Predicate<File>() {
@Override
public boolean test(File e) {
return e.exists();
}
};
public static List<File> existingFilesList(Collection<File> files) {
return filterList(FILE_EXISTS, files);
}
public static Set<File> existingFilesSet(Collection<File> files) {
return filterSet(FILE_EXISTS, files);
}
public static List<File> filterFilesList(Collection<File> files, final FileFilter filter) {
return FP.filterList(new Predicate<File>() {
@Override
public boolean test(File file) {
return filter.accept(file);
}
}, files);
}
}