sventon subversion web client - http://www.sventon.org
[show recent changes]
 
  Help
Rev: HEAD (53458) - http://anonsvn.icesoft.org/repo / bridge-support / patches / bridge-support-sf-12692 / src / main / javascript / collection.js
Show File - collection.js  [show properties]
spinner
/*
 * Copyright 2004-2013 ICEsoft Technologies Canada Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
10   * Unless required by applicable law or agreed to in writing,
11   * software distributed under the License is distributed on an "AS
12   * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13   * express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16 
17  var indexOf = operator($witch(function(condition) {
18      condition(isString, function(items, item) {
19          return items.indexOf(item);
20      });
21 
22      condition(isArray, function(items, item) {
23          for (var i = 0, size = items.length; i < size; i++) {
24              if (items[i] == item) {
25                  return i;
26              }
27          }
28          return -1;
29      });
30 
31      condition(any, operationNotSupported);
32  }));
33 
34  var concatenate = operator(function(items, other) {
35      return items.concat(other);
36  });
37 
38  var append = operator(function(items, item) {
39      if (isArray(items)) {
40          items.push(item);
41          return items;
42      } else {
43          operationNotSupported();
44      }
45  });
46 
47  var insert = operator($witch(function(condition) {
48      condition(isArray, function(items, item) {
49          items.unshift(item);
50          return items;
51      });
52 
53      condition(any, operationNotSupported);
54  }));
55 
56  var each = operator(function(items, iterator) {
57      var size = items.length;
58      for (var i = 0; i < size; i++) iterator(items[i], i);
59  });
60 
61  var inject = operator(function(items, initialValue, injector) {
62      var tally = initialValue;
63      var size = items.length;
64      for (var i = 0; i < size; i++) {
65          tally = injector(tally, items[i]);
66      }
67 
68      return tally;
69  });
70 
71  var select = operator($witch(function(condition) {
72      condition(isArray, function(items, selector) {
73          return inject(items, [], function(tally, item) {
74              return selector(item) ? append(tally, item) : tally;
75          });
76      });
77 
78      condition(isString, function(items, selector) {
79          return inject(items, '', function(tally, item) {
80              return selector(item) ? concatenate(tally, item) : tally;
81          });
82      });
83 
84      condition(isIndexed, function(items, selector) {
85          return Stream(function(cellConstructor) {
86              function selectingStream(start, end) {
87                  if (start > end) return null;
88                  var item = items[start];
89                  return selector(item) ?
90                         function() {
91                             return cellConstructor(item, selectingStream(start + 1, end));
92                         } : selectingStream(start + 1, end);
93 
94              }
95 
96              return selectingStream(0, items.length - 1);
97          });
98      });
99  }));
100 
101  var detect = operator(function(items, iterator, notDetectedThunk) {
102      var size = items.length;
103      for (var i = 0; i < size; i++) {
104          var element = items[i];
105          if (iterator(element, i)) {
106              return element;
107          }
108      }
109 
110      return notDetectedThunk ? notDetectedThunk(items) : null;
111  });
112 
113  var contains = operator($witch(function(condition) {
114      condition(isString, function(items, item) {
115          return items.indexOf(item) > -1;
116      });
117 
118      condition(isArray, function(items, item) {
119          var size = items.length;
120          for (var i = 0; i < size; i++) {
121              if (items[i] == item) {
122                  return true;
123              }
124          }
125 
126          return false;
127      });
128 
129      condition(any, operationNotSupported);
130  }));
131 
132 
133  var size = operator(function(items) {
134      return items.length;
135  });
136 
137  var isEmpty = operator(function(items) {
138      return items.length == 0;
139  });
140 
141  var notEmpty = function(items) {
142      return !isEmpty(items);
143  };
144 
145  var collect = operator($witch(function(condition) {
146      condition(isString, function(items, collector) {
147          return inject(items, '', function(tally, item) {
148              return concatenate(tally, collector(item));
149          });
150      });
151 
152      condition(isArray, function(items, collector) {
153          return inject(items, [], function(tally, item) {
154              return append(tally, collector(item));
155          });
156      });
157 
158      condition(isIndexed, function(items, collector) {
159          return Stream(function(cellConstructor) {
160              function collectingStream(start, end) {
161                  if (start > end) return null;
162                  return function() {
163                      return cellConstructor(collector(items[start], start), collectingStream(start + 1, end));
164                  };
165              }
166 
167              return collectingStream(0, items.length - 1);
168          });
169      });
170  }));
171 
172  var sort = operator(function(items, sorter) {
173      return copy(items).sort(function(a, b) {
174          return sorter(a, b) ? -1 : 1;
175      });
176  });
177 
178  var reverse = operator(function(items) {
179      return copy(items).reverse();
180  });
181 
182  var copy = operator(function(items) {
183      return inject(items, [], curry(append));
184  });
185 
186  var join = operator(function(items, separator) {
187      return items.join(separator);
188  });
189  var inspect = operator();
190 
191  var reject = function(items, rejector) {
192      return select(items, function(i) {
193          return !rejector(i);
194      });
195  };
196 
197  var intersect = operator(function(items, other) {
198      return select(items, curry(contains, other));
199  });
200 
201  var complement = operator(function(items, other) {
202      return reject(items, curry(contains, other));
203  });
204 
205  var broadcast = function(items, args) {
206      args = args || [];
207      each(items, function(i) {
208          apply(i, args);
209      });
210  };
211 
212  var broadcaster = function(items) {
213      return function() {
214          var args = arguments;
215          each(items, function(i) {
216              apply(i, args);
217          });
218      };
219  };
220 
221  var asArray = function(items) {
222      return inject(items, [], append);
223  };
224 
225  var asSet = function(items) {
226      return inject(items, [], function(set, item) {
227          if (not(contains(set, item))) {
228              append(set, item);
229          }
230          return set;
231      });
232  };
233 
234  var key = operator();
235  var value = operator();
236 
237  function Cell(k, v) {
238      return object(function(method) {
239          method(key, function(self) {
240              return k;
241          });
242 
243          method(value, function(self) {
244              return v;
245          });
246 
247          method(asString, function(self) {
248              return 'Cell[' + asString(k) + ': ' + asString(v) + ']';
249          });
250      });
251  }
252 
253  function Stream(streamDefinition) {
254      var stream = streamDefinition(Cell);
255      return object(function(method) {
256          method(each, function(self, iterator) {
257              var cursor = stream;
258              while (cursor != null) {
259                  var cell = cursor();
260                  iterator(key(cell));
261                  cursor = value(cell);
262              }
263          });
264 
265          method(inject, function(self, initialValue, injector) {
266              var tally = initialValue;
267              var cursor = stream;
268              while (cursor != null) {
269                  var cell = cursor();
270                  tally = injector(tally, key(cell));
271                  cursor = value(cell);
272              }
273 
274              return tally;
275          });
276 
277          method(join, function(self, separator) {
278              var tally;
279              var cursor = stream;
280              while (cursor != null) {
281                  var cell = cursor();
282                  var itemAsString = asString(key(cell));
283                  tally = tally ? tally + separator + itemAsString : itemAsString;
284                  cursor = value(cell);
285              }
286              return tally;
287          });
288 
289          method(collect, function(self, collector) {
290              return Stream(function(cellConstructor) {
291                  function collectingStream(stream) {
292                      if (!stream) return null;
293                      var cell = stream();
294                      return function() {
295                          return cellConstructor(collector(key(cell)), collectingStream(value(cell)));
296                      };
297                  }
298 
299                  return collectingStream(stream);
300              });
301          });
302 
303          method(contains, function(self, item) {
304              var cursor = stream;
305              while (cursor != null) {
306                  var cell = cursor();
307                  if (item == key(cell)) return true;
308                  cursor = value(cell);
309              }
310              return false;
311          });
312 
313          method(size, function(self) {
314              var cursor = stream;
315              var i = 0;
316              while (cursor != null) {
317                  i++;
318                  cursor = value(cursor());
319              }
320 
321              return i;
322          });
323 
324          method(select, function(self, selector) {
325              return Stream(function(cellConstructor) {
326                  function select(stream) {
327                      if (!stream) return null;
328                      var cell = stream();
329                      var k = key(cell);
330                      var v = value(cell);
331                      return selector(k) ? function() {
332                          return cellConstructor(k, select(v));
333                      } : select(v);
334                  }
335 
336                  return select(stream);
337              });
338          });
339 
340          method(detect, function(self, detector, notDetectedThunk) {
341              var cursor = stream;
342              var result;
343              while (cursor != null) {
344                  var cell = cursor();
345                  var k = key(cell);
346                  if (detector(k)) {
347                      result = k;
348                      break;
349                  }
350                  cursor = value(cell);
351              }
352 
353              if (result) {
354                  return result;
355              } else {
356                  return notDetectedThunk ? notDetectedThunk(self) : null;
357              }
358          });
359 
360          method(isEmpty, function(self) {
361              return stream == null;
362          });
363 
364          method(copy, function(self) {
365              return Stream(streamDefinition);
366          });
367 
368          method(asString, function(self) {
369              return 'Stream[' + join(self, ', ') + ']';
370          });
371      });
372  }


feed icon

sventon 2.5.1