]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/Lists.java
Improvement of index and group implementations and indexGroup(By)
[simantics/platform.git] / bundles / org.simantics.scl.runtime / src / org / simantics / scl / runtime / Lists.java
index a5722763551855d4d60525066732ba9943420d8c..5259ce6315a38b5b9b1ab64f94ce452cb82930ca 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.scl.runtime;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
@@ -12,6 +13,7 @@ import org.simantics.scl.runtime.function.FunctionImpl2;
 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;
 
@@ -227,9 +229,33 @@ public class Lists {
         };
     }
     
+    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
@@ -256,6 +282,81 @@ public class Lists {
         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() {
@@ -292,10 +393,42 @@ public class Lists {
         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;
     }
 }