]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/Lists.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.scl.runtime / src / org / simantics / scl / runtime / Lists.java
1 package org.simantics.scl.runtime;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Comparator;
6 import java.util.Iterator;
7 import java.util.List;
8
9 import org.simantics.scl.runtime.function.Function;
10 import org.simantics.scl.runtime.function.FunctionImpl1;
11 import org.simantics.scl.runtime.function.FunctionImpl2;
12 import org.simantics.scl.runtime.tuple.Tuple2;
13
14 import gnu.trove.map.hash.TCustomHashMap;
15 import gnu.trove.set.hash.THashSet;
16 import gnu.trove.strategy.HashingStrategy;
17
18
19 @SuppressWarnings({"rawtypes", "unchecked"})
20 public class Lists {
21     
22     public static List map(Function f, List l) {
23         ArrayList result = new ArrayList(l.size());
24         for(Object a : l)
25             result.add(f.apply(a));
26         return result;
27     }
28     
29     public static void iter(Function f, List l) {
30         for(Object a : l)
31             f.apply(a);
32     }
33     
34     public static List filter(Function p, List l) {
35         ArrayList result = new ArrayList(Math.min(10, l.size()));
36         for(Object a : l)
37             if((Boolean)p.apply(a))
38                 result.add(a);
39         return result;
40     }
41     
42     public static List filterJust(List l) {
43         ArrayList result = new ArrayList(Math.min(10, l.size()));
44         for(Object a : l)
45             if(a != null)
46                 result.add(a);
47         return result;
48     }
49     
50     public static List reverse(List l) {
51         ArrayList result = new ArrayList(l.size());
52         for(int i=l.size()-1;i>=0;--i)
53             result.add(l.get(i));
54         return result;
55     }
56     
57     public static Object foldl(Function f, Object initial, List l) {
58         for(Object a : l)
59             initial = f.apply(initial, a);
60         return initial;
61     }    
62     
63     // (b -> Maybe (a, b)) -> b -> [a]
64     public static List unfoldr(Function f, Object state) {
65         ArrayList result = new ArrayList();
66         while(true) {
67             Object r = f.apply(state);
68             if(r == null)
69                 return result;
70             Tuple2 t = (Tuple2)r;
71             result.add(t.c0);
72             state = t.c1;
73         }
74     }
75     
76     public static Object foldr(Function f, Object initial, List l) {
77         for(int i=l.size()-1;i>=0;--i)
78             initial = f.apply(initial, l.get(i));
79         return initial;
80     }
81     
82     public static Object foldl1(Function f, List l) {
83         Iterator it = l.iterator();
84         Object initial = it.next();
85         while(it.hasNext())
86             initial = f.apply(initial, it.next());
87         return initial;
88     }
89     
90     public static Object foldr1(Function f, List l) {
91         int i=l.size()-1;
92         Object initial = l.get(i);
93         for(--i;i>=0;--i)
94             initial = f.apply(initial, l.get(i));
95         return initial;
96     }
97     
98     public static List _pp(List a, List b) {
99         ArrayList result = new ArrayList(a.size() + b.size());
100         result.addAll(a);
101         result.addAll(b);
102         return result;
103     }
104     
105     public static List concat(List l) {
106         int size = 0;
107         for(Object e : l)
108             size += ((List)e).size();
109         ArrayList result = new ArrayList(size);
110         for(Object e : l)
111             result.addAll((List)e);
112         return result;
113     }
114     
115     public static List append(List a, List b) {
116         ArrayList result = new ArrayList(a.size() + b.size());
117         result.addAll(a);
118         result.addAll(b);
119         return result;
120     }
121     
122     public static List concatMap(Function f, List l) {
123         return concat(map(f, l));
124     }
125     
126     public static int length(List l) {
127         return l.size();
128     }
129     
130     public static boolean forall(Function p, List l) {
131         for(Object e : l)
132             if(!(Boolean)p.apply(e))
133                 return false;
134         return true;
135     }
136     
137     public static boolean exists(Function p, List l) {
138         for(Object e : l)
139             if((Boolean)p.apply(e))
140                 return true;
141         return false;
142     }
143     
144     public static Object get(List l, double i) {
145         return l.get((int)i);
146     }
147
148     private static final FunctionImpl2 BUILD_FUNC = new FunctionImpl2() {
149         @Override
150         public Object apply(Object p0, Object p1) {
151             ((ArrayList)p0).add(p1);
152             return p0;
153         }
154     };
155     
156     public static List build(Function f) {
157         return (List)f.apply(new ArrayList(), BUILD_FUNC);
158     }
159     
160     public static List range(int from, int to) {
161         ArrayList result = new ArrayList();
162         while(from <= to) {
163             result.add(from);
164             ++from;
165         }
166         return result;
167     }
168     
169     public static List newList() {
170         return new ArrayList(2);
171     }
172     
173     public static void add(List a, Object b) {
174         a.add(b);
175     }
176     
177     public static List zip(List a, List b) {
178         int len = Math.min(a.size(), b.size());        
179         ArrayList result = new ArrayList(len);
180         for(int i=0;i<len;++i)
181             result.add(new Tuple2(a.get(i), b.get(i)));
182         return result;
183     }
184     
185     public static List zipWith(Function f, List a, List b) {
186         int len = Math.min(a.size(), b.size());        
187         ArrayList result = new ArrayList(len);
188         for(int i=0;i<len;++i)
189             result.add(f.apply(a.get(i), b.get(i)));
190         return result;
191     }
192     
193     public static Tuple2 unzip(List in) {
194         int len = in.size();
195         ArrayList a = new ArrayList(len);        
196         ArrayList b = new ArrayList(len);        
197         for(int i=0;i<len;++i) {
198             Tuple2 tuple = (Tuple2)in.get(i);
199             a.add(tuple.c0);
200             b.add(tuple.c1);
201         }
202         return new Tuple2(a, b);
203     }
204     
205     public static Function indexWith(final Function hash, final Function eq, List<Tuple2> l) {
206         final TCustomHashMap<Object,Object> map = new TCustomHashMap<Object,Object>(
207                 new HashingStrategy<Object>() {
208                     private static final long serialVersionUID = 3130052128660420673L;
209
210                     @Override
211                     public int computeHashCode(Object object) {
212                         return (Integer)hash.apply(object);
213                     }
214
215                     @Override
216                     public boolean equals(Object o1, Object o2) {
217                         return (Boolean)eq.apply(o1, o2);
218                     }
219                 });
220         for(Tuple2 t : l)
221             map.put(t.c0, t.c1);
222         return new FunctionImpl1<Object,Object>() {
223             @Override
224             public Object apply(Object p0) {
225                 return map.get(p0);
226             }
227         };
228     }
229     
230     // groupWith :: (a -> Integer) -> (a -> a -> Boolean) -> (a -> b) -> [a] -> [(b, [a])]
231     @SuppressWarnings("serial")
232     public static ArrayList<Tuple2> groupWith(final Function hash, final Function eq, Function keyFunction, Function valueFunction, List<Object> input) {
233         final TCustomHashMap<Object,ArrayList<Object>> map = new TCustomHashMap<Object,ArrayList<Object>>(
234                 new HashingStrategy<Object>() {
235                     @Override
236                     public int computeHashCode(Object object) {
237                         return (Integer)hash.apply(object);
238                     }
239
240                     @Override
241                     public boolean equals(Object o1, Object o2) {
242                         return (Boolean)eq.apply(o1, o2);
243                     }
244                 });
245         ArrayList<Tuple2> result = new ArrayList<Tuple2>();
246         for(Object o : input) {
247             Object key = keyFunction.apply(o);
248             ArrayList<Object> l = map.get(key);
249             if(l == null) {
250                 l = new ArrayList<Object>();
251                 map.put(key, l);
252                 result.add(new Tuple2(key, l));
253             }
254             l.add(valueFunction.apply(o));
255         }
256         return result;
257     }
258     
259     public static List sortWith(final Function compare, List l) {
260         Object[] result = l.toArray(new Object[l.size()]);
261         Arrays.sort(result, new Comparator() {
262             @Override
263             public int compare(Object o1, Object o2) {
264                 return (Integer)compare.apply(o1, o2);
265             }            
266         });
267         return Arrays.asList(result);
268     }
269     
270     public static List uniqueWith(Function compare, List l) {
271         ArrayList result = new ArrayList(Math.min(10, l.size()));
272         outerLoop:
273         for(int i=0;i<l.size();++i) {
274             Object el = l.get(i);
275             for(int j=0;j<result.size();++j)
276                 if(compare.apply(el, result.get(j)).equals(Boolean.TRUE))
277                     continue outerLoop;
278             result.add(el);
279         }
280         return result;
281     }
282     
283     public static List deleteAllBy(Function compare, List a, List b) {
284         ArrayList result = new ArrayList(Math.min(10, a.size()));
285         outerLoop:
286         for(Object el : a) {
287             for(Object el2 : b)
288                 if(compare.apply(el, el2).equals(Boolean.TRUE))
289                     continue outerLoop;
290             result.add(el);
291         }        
292         return result;
293     }
294     
295     public static List<Object> unique(List<Object> l) {
296         THashSet<Object> set = new THashSet<Object>();
297         for(Object el : l)
298             set.add(el);
299         return Arrays.asList(set.toArray(new Object[set.size()]));
300     }
301 }