import java.util.ArrayList;
import java.util.Collection;

public class Enumerable {
	
	public static <T, U> Collection<U> map(Collection<T> c, Filter<T, U> f) {
		ArrayList<U> result = new ArrayList<U>();
		
		for (T e : c) {
			result.add(f.apply(e));
		}
		
		return result;
	}
	
	public static <T, U> Collection<U> map(T[] c, Filter<T, U> f) {
		ArrayList<U> result = new ArrayList<U>();
		
		for (T e : c) {
			result.add(f.apply(e));
		}
		
		return result;
	}
	
	public static <T> Collection<T> select(Collection<T> c, Predicate<T> p) {
		ArrayList<T> result = new ArrayList<T>();
		
		for (T e : c) {
			if (p.apply(e)) {
				result.add(e);
			}
		}
		
		return result;
	}
	
	public static <T> Collection<T> select(T[] c, Predicate<T> p) {
		ArrayList<T> result = new ArrayList<T>();
		
		for (T e : c) {
			if (p.apply(e)) {
				result.add(e);
			}
		}
		
		return result;
	}
	
	public static <T> Collection<T> reject(Collection<T> c, Predicate<T> p) {
		ArrayList<T> result = new ArrayList<T>();
		
		for (T e : c) {
			if (! p.apply(e)) {
				result.add(e);
			}
		}
		
		return result;
	}
	
	public static <T> Collection<T> reject(T[] c, Predicate<T> p) {
		ArrayList<T> result = new ArrayList<T>();
		
		for (T e : c) {
			if (! p.apply(e)) {
				result.add(e);
			}
		}
		
		return result;
	}
	
	public static <T> boolean all(Collection<T> c, Predicate<T> p) {
		for (T e : c) {
			if (! p.apply(e)) {
				return false;
			}
		}
		
		return true;
	}
	
	public static <T> boolean all(T[] c, Predicate<T> p) {
		for (T e : c) {
			if (! p.apply(e)) {
				return false;
			}
		}
		
		return true;
	}
	
	public static <T> boolean any(Collection<T> c, Predicate<T> p) {
		for (T e : c) {
			if (p.apply(e)) {
				return true;
			}
		}
		
		return false;
	}
	
	public static <T> boolean any(T[] c, Predicate<T> p) {
		for (T e : c) {
			if (p.apply(e)) {
				return true;
			}
		}
		
		return false;
	}

}
