package org.lambda.query; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import org.lambda.functions.Function1; import org.lambda.query.OrderBy.Order; import com.spun.util.ArrayUtils; public class Query<In> { public static <In, Out> List<Out> select(List<In> list, Function1<In, Out> function) { ArrayList<Out> out = new ArrayList<Out>(); for (In i : list) { out.add(function.call(i)); } return out; } public static <In, Out> List<Out> select(In[] list, Function1<In, Out> function) { return select(Arrays.asList(list), function); } public static <In> List<In> where(Iterable<In> list, Function1<In, Boolean> funct) { ArrayList<In> out = new ArrayList<In>(); for (In i : list) { if (funct.call(i)) { out.add(i); } } return out; } public static <In> List<In> where(In[] list, Function1<In, Boolean> funct) { ArrayList<In> out = new ArrayList<In>(); for (In i : list) { if (funct.call(i)) { out.add(i); } } return out; } public static <In> In max(List<In> list, Function1<In, Comparable> f1) { return getTop(list, f1, 1); } public static <In> In min(List<In> list, Function1<In, Comparable> f1) { return getTop(list, f1, -1); } public static <In> Double average(List<In> list, Function1<In, Number> f1) { double total = 0.00; for (In in : list) { total += f1.call(in).doubleValue(); } return total / list.size(); } private static <In> In getTop(List<In> list, Function1<In, Comparable> f1, int modifier) { if (ArrayUtils.isEmpty(list)) { return null; } In found = list.get(0); Comparable max = f1.call(found); for (In in : list) { Comparable current = f1.call(in); if (max.compareTo(current) * modifier < 0) { max = current; found = in; } } return found; } public static <T> T[] orderBy(T[] list, Function1<T, Comparable> f1) { return orderBy(list, Order.Ascending, f1); } public static <T> T[] orderBy(T[] list, Order order, Function1<T, Comparable> f1) { Arrays.sort(list, new OrderBy(order, f1)); return list; } public static <T> List<T> orderBy(List<T> list, Function1<T, Comparable> f1) { return orderBy(list, Order.Ascending, f1); } public static <T> List<T> orderBy(List<T> list, Order order, Function1<T, Comparable> f1) { Collections.sort(list, new OrderBy(order, f1)); return list; } public static <In, Out extends Number> Double sum(In[] list, Function1<In, Out> f1) { return sum(Arrays.asList(list), f1); } public static <In, Out extends Number> Double sum(Collection<In> list, Function1<In, Out> f1) { double sum = 0; for (In in : list) { sum += f1.call(in).doubleValue(); } return sum; } public static <Out extends Number> Double sum(Collection<Out> list) { return sum(list, new Echo1<Out>()); } public static <Out extends Number> Double sum(Out[] list) { return sum(list, new Echo1<Out>()); } public static <T extends Number> T max(List<T> numbers) { return (T) max((List) numbers, new Echo1<Comparable>()); } public static <T extends Number> T max(T[] numbers) { return max(Arrays.asList(numbers)); } public static <T extends Number> T min(List<T> numbers) { return (T) min((List) numbers, new Echo1<Comparable>()); } }