"Sorts the list using the given comparator."
sortWith :: (a -> a -> <e> Integer) -> [a] -> <e> [a]
+
+ """
+ Given a list of key-value pairs, the function produces a function that finds a value
+ efficiently for the given key.
+ """
+ index :: [(a,b)] -> a -> Maybe b
+
+ """
+ Given a list of values and a function computing a key for each value, the function produces a function that finds a value
+ effeciently for the given key.
+ """
+ indexBy :: (a -> b) -> [a] -> b -> Maybe a
+
"Works like `index` but uses the given functions as hash codes and equality."
indexWith :: (a -> Integer) -> (a -> a -> Boolean) -> [(a,b)] -> a -> Maybe b
+
+ "Groups a list values by a key computed by the given function."
+ groupBy :: (a -> <e> b) -> [a] -> <e> [(b, [a])]
+
+ "Groups a list of key-value pairs by the keys."
+ group :: [(a,b)] -> [(a, [b])]
+
+ "Composition of index and groupBy."
+ indexGroupBy :: (a -> <e> b) -> [a] -> <e> (b -> [a])
+
+ "Composition of index and group."
+ indexGroup :: [(a,b)] -> a -> [b]
+
groupWith :: (b -> Integer) -> (b -> b -> Boolean) -> (a -> <e> b) -> (a -> <e> c) -> [a] -> <e> [(b, [c])]
+
+ "Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
+ unique :: [a] -> [a]
+
+ "Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
+ uniqueBy :: (a -> b) -> [a] -> [a]
+
"Works like `unique` but uses the given function for equality tests."
uniqueWith :: (a -> a -> Boolean) -> [a] -> [a]
+
"Works like `\\\\` but uses the given function for equality tests."
deleteAllBy :: (a -> a -> Boolean) -> [a] -> [a] -> [a]
+ @private
+ listDifference :: [a] -> [a] -> [a]
+
//range :: Integer -> Integer -> [Integer]
//build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
// This is faster if f is slow, but will generate more auxiliary structures
//sortBy f l = map snd (sortWith (\(x,_) (y,_) -> compare x y) [(f x, x) | x <- l])
-"""
-Given a list of key-value pairs, the function produces a function that finds a value
-efficiently for the given key.
-"""
-index :: [(a,b)] -> a -> Maybe b
-index = indexWith hashCode (==)
-
-"""
-Given a list of values and a function computing a key for each value, the function produces a function that finds a value
-effeciently for the given key.
-"""
-indexBy :: (a -> b) -> [a] -> b -> Maybe a
-indexBy f l = index [(f x, x) | x <- l]
-
-"Groups a list values by a key computed by the given function."
-groupBy :: (a -> <e> b) -> [a] -> <e> [(b, [a])]
-groupBy f l = groupWith hashCode (==) f id l
-
-"Groups a list of key-value pairs by the keys."
-group :: [(a,b)] -> [(a, [b])]
-group = groupWith hashCode (==) fst snd
-
-"Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
-unique :: [a] -> [a]
-unique = uniqueWith (==)
-
-"Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
-uniqueBy :: (a -> b) -> [a] -> [a]
-uniqueBy f = uniqueWith (\a b -> f a == f b)
-
-//sortAndUniqueBy :: Ord b => (a -> b) -> [a] -> [a]
-//sortAndUniqueBy f = map snd . uniqueWith (\a b -> fst a == fst b) . sortBy fst . map (\x -> (f x, x))
-
"`a \\\\ b` removes all elements of `b` from the list `a`."
(\\) :: [a] -> [a] -> [a]
-(\\) = deleteAllBy (==)
+(\\) = listDifference
/// Dynamic ///
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.simantics.scl.runtime.tuple.Tuple2;
import gnu.trove.map.hash.TCustomHashMap;
+import gnu.trove.map.hash.THashMap;
import gnu.trove.set.hash.THashSet;
import gnu.trove.strategy.HashingStrategy;
};
}
+ public static Function index(List<Tuple2> l) {
+ THashMap map = new THashMap(l.size());
+ for(Tuple2 t : l)
+ map.put(t.c0, t.c1);
+ return new FunctionImpl1<Object,Object>() {
+ @Override
+ public Object apply(Object p0) {
+ return map.get(p0);
+ }
+ };
+ }
+
+ public static Function indexBy(Function f, List l) {
+ THashMap map = new THashMap(l.size());
+ for(Object o : l)
+ map.put(f.apply(o), o);
+ return new FunctionImpl1<Object,Object>() {
+ @Override
+ public Object apply(Object p0) {
+ return map.get(p0);
+ }
+ };
+ }
+
// groupWith :: (a -> Integer) -> (a -> a -> Boolean) -> (a -> b) -> [a] -> [(b, [a])]
@SuppressWarnings("serial")
- public static ArrayList<Tuple2> groupWith(final Function hash, final Function eq, Function keyFunction, Function valueFunction, List<Object> input) {
+ public static List<Tuple2> groupWith(final Function hash, final Function eq, Function keyFunction, Function valueFunction, List<Object> input) {
final TCustomHashMap<Object,ArrayList<Object>> map = new TCustomHashMap<Object,ArrayList<Object>>(
new HashingStrategy<Object>() {
@Override
return result;
}
+ public static List<Tuple2> group(List<Tuple2> input) {
+ THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
+ ArrayList<Tuple2> result = new ArrayList<Tuple2>();
+ for(Tuple2 t : input) {
+ Object key = t.c0;
+ ArrayList<Object> list = groupMap.get(key);
+ if(list == null) {
+ list = new ArrayList<Object>();
+ groupMap.put(key, list);
+ result.add(new Tuple2(key, list));
+ }
+ list.add(t.c1);
+ }
+ return result;
+ }
+
+ public static List<Tuple2> groupBy(Function f, List<Tuple2> input) {
+ THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
+ ArrayList<Tuple2> result = new ArrayList<Tuple2>();
+ for(Object value : input) {
+ Object key = f.apply(value);
+ ArrayList<Object> list = groupMap.get(key);
+ if(list == null) {
+ list = new ArrayList<Object>();
+ groupMap.put(key, list);
+ result.add(new Tuple2(key, list));
+ }
+ list.add(value);
+ }
+ return result;
+ }
+
+ private static class GroupMapFunction extends FunctionImpl1<Object, List<Object>> {
+ THashMap<Object, ArrayList<Object>> groupMap;
+ public GroupMapFunction(THashMap<Object, ArrayList<Object>> groupMap) {
+ this.groupMap = groupMap;
+ }
+ @Override
+ public List<Object> apply(Object p0) {
+ List<Object> result = groupMap.get(p0);
+ if(result == null)
+ return Collections.emptyList();
+ else
+ return result;
+ }
+ }
+
+ public static Function indexGroup(List<Tuple2> input) {
+ THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
+ for(Tuple2 t : input) {
+ Object key = t.c0;
+ ArrayList<Object> list = groupMap.get(key);
+ if(list == null) {
+ list = new ArrayList<Object>();
+ groupMap.put(key, list);
+ }
+ list.add(t.c1);
+ }
+ return new GroupMapFunction(groupMap);
+ }
+
+ public static Function indexGroupBy(Function f, List<Tuple2> input) {
+ THashMap<Object, ArrayList<Object>> groupMap = new THashMap<Object, ArrayList<Object>>();
+ for(Object value : input) {
+ Object key = f.apply(value);
+ ArrayList<Object> list = groupMap.get(key);
+ if(list == null) {
+ list = new ArrayList<Object>();
+ groupMap.put(key, list);
+ }
+ list.add(value);
+ }
+ return new GroupMapFunction(groupMap);
+ }
+
public static List sortWith(final Function compare, List l) {
Object[] result = l.toArray(new Object[l.size()]);
Arrays.sort(result, new Comparator() {
return result;
}
+ public static List listDifference(List a, List b) {
+ if(a.isEmpty() || b.isEmpty())
+ return a;
+ THashSet setB = new THashSet(b);
+ for(int i=0;i<a.size();++i) {
+ Object el = a.get(i);
+ if(setB.contains(el)) {
+ ArrayList result = new ArrayList(a.size()-1);
+ for(int j=0;j<i;++j)
+ result.add(a.get(j));
+ for(++i;i<a.size();++i) {
+ el = a.get(i);
+ if(!setB.contains(el))
+ result.add(el);
+ }
+ return result;
+ }
+ }
+ return a;
+ }
+
public static List<Object> unique(List<Object> l) {
- THashSet<Object> set = new THashSet<Object>();
+ THashSet<Object> set = new THashSet<Object>(l.size());
+ ArrayList<Object> result = new ArrayList<Object>(l.size());
+ for(Object el : l)
+ if(set.add(el))
+ result.add(el);
+ return result;
+ }
+
+ public static List<Object> uniqueBy(Function f, List<Object> l) {
+ THashSet<Object> set = new THashSet<Object>(l.size());
+ ArrayList<Object> result = new ArrayList<Object>(l.size());
for(Object el : l)
- set.add(el);
- return Arrays.asList(set.toArray(new Object[set.size()]));
+ if(set.add(f.apply(el)))
+ result.add(el);
+ return result;
}
}