1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mochitest/MochiKit/Iter.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,843 @@ 1.4 +/*** 1.5 + 1.6 +MochiKit.Iter 1.4 1.7 + 1.8 +See <http://mochikit.com/> for documentation, downloads, license, etc. 1.9 + 1.10 +(c) 2005 Bob Ippolito. All rights Reserved. 1.11 + 1.12 +***/ 1.13 + 1.14 +if (typeof(dojo) != 'undefined') { 1.15 + dojo.provide('MochiKit.Iter'); 1.16 + dojo.require('MochiKit.Base'); 1.17 +} 1.18 + 1.19 +if (typeof(JSAN) != 'undefined') { 1.20 + JSAN.use("MochiKit.Base", []); 1.21 +} 1.22 + 1.23 +try { 1.24 + if (typeof(MochiKit.Base) == 'undefined') { 1.25 + throw ""; 1.26 + } 1.27 +} catch (e) { 1.28 + throw "MochiKit.Iter depends on MochiKit.Base!"; 1.29 +} 1.30 + 1.31 +if (typeof(MochiKit.Iter) == 'undefined') { 1.32 + MochiKit.Iter = {}; 1.33 +} 1.34 + 1.35 +MochiKit.Iter.NAME = "MochiKit.Iter"; 1.36 +MochiKit.Iter.VERSION = "1.4"; 1.37 +MochiKit.Base.update(MochiKit.Iter, { 1.38 + __repr__: function () { 1.39 + return "[" + this.NAME + " " + this.VERSION + "]"; 1.40 + }, 1.41 + toString: function () { 1.42 + return this.__repr__(); 1.43 + }, 1.44 + 1.45 + /** @id MochiKit.Iter.registerIteratorFactory */ 1.46 + registerIteratorFactory: function (name, check, iterfactory, /* optional */ override) { 1.47 + MochiKit.Iter.iteratorRegistry.register(name, check, iterfactory, override); 1.48 + }, 1.49 + 1.50 + /** @id MochiKit.Iter.iter */ 1.51 + iter: function (iterable, /* optional */ sentinel) { 1.52 + var self = MochiKit.Iter; 1.53 + if (arguments.length == 2) { 1.54 + return self.takewhile( 1.55 + function (a) { return a != sentinel; }, 1.56 + iterable 1.57 + ); 1.58 + } 1.59 + if (typeof(iterable.next) == 'function') { 1.60 + return iterable; 1.61 + } else if (typeof(iterable.iter) == 'function') { 1.62 + return iterable.iter(); 1.63 + /* 1.64 + } else if (typeof(iterable.__iterator__) == 'function') { 1.65 + // 1.66 + // XXX: We can't support JavaScript 1.7 __iterator__ directly 1.67 + // because of Object.prototype.__iterator__ 1.68 + // 1.69 + return iterable.__iterator__(); 1.70 + */ 1.71 + } 1.72 + 1.73 + try { 1.74 + return self.iteratorRegistry.match(iterable); 1.75 + } catch (e) { 1.76 + var m = MochiKit.Base; 1.77 + if (e == m.NotFound) { 1.78 + e = new TypeError(typeof(iterable) + ": " + m.repr(iterable) + " is not iterable"); 1.79 + } 1.80 + throw e; 1.81 + } 1.82 + }, 1.83 + 1.84 + /** @id MochiKit.Iter.count */ 1.85 + count: function (n) { 1.86 + if (!n) { 1.87 + n = 0; 1.88 + } 1.89 + var m = MochiKit.Base; 1.90 + return { 1.91 + repr: function () { return "count(" + n + ")"; }, 1.92 + toString: m.forwardCall("repr"), 1.93 + next: m.counter(n) 1.94 + }; 1.95 + }, 1.96 + 1.97 + /** @id MochiKit.Iter.cycle */ 1.98 + cycle: function (p) { 1.99 + var self = MochiKit.Iter; 1.100 + var m = MochiKit.Base; 1.101 + var lst = []; 1.102 + var iterator = self.iter(p); 1.103 + return { 1.104 + repr: function () { return "cycle(...)"; }, 1.105 + toString: m.forwardCall("repr"), 1.106 + next: function () { 1.107 + try { 1.108 + var rval = iterator.next(); 1.109 + lst.push(rval); 1.110 + return rval; 1.111 + } catch (e) { 1.112 + if (e != self.StopIteration) { 1.113 + throw e; 1.114 + } 1.115 + if (lst.length === 0) { 1.116 + this.next = function () { 1.117 + throw self.StopIteration; 1.118 + }; 1.119 + } else { 1.120 + var i = -1; 1.121 + this.next = function () { 1.122 + i = (i + 1) % lst.length; 1.123 + return lst[i]; 1.124 + }; 1.125 + } 1.126 + return this.next(); 1.127 + } 1.128 + } 1.129 + }; 1.130 + }, 1.131 + 1.132 + /** @id MochiKit.Iter.repeat */ 1.133 + repeat: function (elem, /* optional */n) { 1.134 + var m = MochiKit.Base; 1.135 + if (typeof(n) == 'undefined') { 1.136 + return { 1.137 + repr: function () { 1.138 + return "repeat(" + m.repr(elem) + ")"; 1.139 + }, 1.140 + toString: m.forwardCall("repr"), 1.141 + next: function () { 1.142 + return elem; 1.143 + } 1.144 + }; 1.145 + } 1.146 + return { 1.147 + repr: function () { 1.148 + return "repeat(" + m.repr(elem) + ", " + n + ")"; 1.149 + }, 1.150 + toString: m.forwardCall("repr"), 1.151 + next: function () { 1.152 + if (n <= 0) { 1.153 + throw MochiKit.Iter.StopIteration; 1.154 + } 1.155 + n -= 1; 1.156 + return elem; 1.157 + } 1.158 + }; 1.159 + }, 1.160 + 1.161 + /** @id MochiKit.Iter.next */ 1.162 + next: function (iterator) { 1.163 + return iterator.next(); 1.164 + }, 1.165 + 1.166 + /** @id MochiKit.Iter.izip */ 1.167 + izip: function (p, q/*, ...*/) { 1.168 + var m = MochiKit.Base; 1.169 + var self = MochiKit.Iter; 1.170 + var next = self.next; 1.171 + var iterables = m.map(self.iter, arguments); 1.172 + return { 1.173 + repr: function () { return "izip(...)"; }, 1.174 + toString: m.forwardCall("repr"), 1.175 + next: function () { return m.map(next, iterables); } 1.176 + }; 1.177 + }, 1.178 + 1.179 + /** @id MochiKit.Iter.ifilter */ 1.180 + ifilter: function (pred, seq) { 1.181 + var m = MochiKit.Base; 1.182 + seq = MochiKit.Iter.iter(seq); 1.183 + if (pred === null) { 1.184 + pred = m.operator.truth; 1.185 + } 1.186 + return { 1.187 + repr: function () { return "ifilter(...)"; }, 1.188 + toString: m.forwardCall("repr"), 1.189 + next: function () { 1.190 + while (true) { 1.191 + var rval = seq.next(); 1.192 + if (pred(rval)) { 1.193 + return rval; 1.194 + } 1.195 + } 1.196 + // mozilla warnings aren't too bright 1.197 + return undefined; 1.198 + } 1.199 + }; 1.200 + }, 1.201 + 1.202 + /** @id MochiKit.Iter.ifilterfalse */ 1.203 + ifilterfalse: function (pred, seq) { 1.204 + var m = MochiKit.Base; 1.205 + seq = MochiKit.Iter.iter(seq); 1.206 + if (pred === null) { 1.207 + pred = m.operator.truth; 1.208 + } 1.209 + return { 1.210 + repr: function () { return "ifilterfalse(...)"; }, 1.211 + toString: m.forwardCall("repr"), 1.212 + next: function () { 1.213 + while (true) { 1.214 + var rval = seq.next(); 1.215 + if (!pred(rval)) { 1.216 + return rval; 1.217 + } 1.218 + } 1.219 + // mozilla warnings aren't too bright 1.220 + return undefined; 1.221 + } 1.222 + }; 1.223 + }, 1.224 + 1.225 + /** @id MochiKit.Iter.islice */ 1.226 + islice: function (seq/*, [start,] stop[, step] */) { 1.227 + var self = MochiKit.Iter; 1.228 + var m = MochiKit.Base; 1.229 + seq = self.iter(seq); 1.230 + var start = 0; 1.231 + var stop = 0; 1.232 + var step = 1; 1.233 + var i = -1; 1.234 + if (arguments.length == 2) { 1.235 + stop = arguments[1]; 1.236 + } else if (arguments.length == 3) { 1.237 + start = arguments[1]; 1.238 + stop = arguments[2]; 1.239 + } else { 1.240 + start = arguments[1]; 1.241 + stop = arguments[2]; 1.242 + step = arguments[3]; 1.243 + } 1.244 + return { 1.245 + repr: function () { 1.246 + return "islice(" + ["...", start, stop, step].join(", ") + ")"; 1.247 + }, 1.248 + toString: m.forwardCall("repr"), 1.249 + next: function () { 1.250 + var rval; 1.251 + while (i < start) { 1.252 + rval = seq.next(); 1.253 + i++; 1.254 + } 1.255 + if (start >= stop) { 1.256 + throw self.StopIteration; 1.257 + } 1.258 + start += step; 1.259 + return rval; 1.260 + } 1.261 + }; 1.262 + }, 1.263 + 1.264 + /** @id MochiKit.Iter.imap */ 1.265 + imap: function (fun, p, q/*, ...*/) { 1.266 + var m = MochiKit.Base; 1.267 + var self = MochiKit.Iter; 1.268 + var iterables = m.map(self.iter, m.extend(null, arguments, 1)); 1.269 + var map = m.map; 1.270 + var next = self.next; 1.271 + return { 1.272 + repr: function () { return "imap(...)"; }, 1.273 + toString: m.forwardCall("repr"), 1.274 + next: function () { 1.275 + return fun.apply(this, map(next, iterables)); 1.276 + } 1.277 + }; 1.278 + }, 1.279 + 1.280 + /** @id MochiKit.Iter.applymap */ 1.281 + applymap: function (fun, seq, self) { 1.282 + seq = MochiKit.Iter.iter(seq); 1.283 + var m = MochiKit.Base; 1.284 + return { 1.285 + repr: function () { return "applymap(...)"; }, 1.286 + toString: m.forwardCall("repr"), 1.287 + next: function () { 1.288 + return fun.apply(self, seq.next()); 1.289 + } 1.290 + }; 1.291 + }, 1.292 + 1.293 + /** @id MochiKit.Iter.chain */ 1.294 + chain: function (p, q/*, ...*/) { 1.295 + // dumb fast path 1.296 + var self = MochiKit.Iter; 1.297 + var m = MochiKit.Base; 1.298 + if (arguments.length == 1) { 1.299 + return self.iter(arguments[0]); 1.300 + } 1.301 + var argiter = m.map(self.iter, arguments); 1.302 + return { 1.303 + repr: function () { return "chain(...)"; }, 1.304 + toString: m.forwardCall("repr"), 1.305 + next: function () { 1.306 + while (argiter.length > 1) { 1.307 + try { 1.308 + return argiter[0].next(); 1.309 + } catch (e) { 1.310 + if (e != self.StopIteration) { 1.311 + throw e; 1.312 + } 1.313 + argiter.shift(); 1.314 + } 1.315 + } 1.316 + if (argiter.length == 1) { 1.317 + // optimize last element 1.318 + var arg = argiter.shift(); 1.319 + this.next = m.bind("next", arg); 1.320 + return this.next(); 1.321 + } 1.322 + throw self.StopIteration; 1.323 + } 1.324 + }; 1.325 + }, 1.326 + 1.327 + /** @id MochiKit.Iter.takewhile */ 1.328 + takewhile: function (pred, seq) { 1.329 + var self = MochiKit.Iter; 1.330 + seq = self.iter(seq); 1.331 + return { 1.332 + repr: function () { return "takewhile(...)"; }, 1.333 + toString: MochiKit.Base.forwardCall("repr"), 1.334 + next: function () { 1.335 + var rval = seq.next(); 1.336 + if (!pred(rval)) { 1.337 + this.next = function () { 1.338 + throw self.StopIteration; 1.339 + }; 1.340 + this.next(); 1.341 + } 1.342 + return rval; 1.343 + } 1.344 + }; 1.345 + }, 1.346 + 1.347 + /** @id MochiKit.Iter.dropwhile */ 1.348 + dropwhile: function (pred, seq) { 1.349 + seq = MochiKit.Iter.iter(seq); 1.350 + var m = MochiKit.Base; 1.351 + var bind = m.bind; 1.352 + return { 1.353 + "repr": function () { return "dropwhile(...)"; }, 1.354 + "toString": m.forwardCall("repr"), 1.355 + "next": function () { 1.356 + while (true) { 1.357 + var rval = seq.next(); 1.358 + if (!pred(rval)) { 1.359 + break; 1.360 + } 1.361 + } 1.362 + this.next = bind("next", seq); 1.363 + return rval; 1.364 + } 1.365 + }; 1.366 + }, 1.367 + 1.368 + _tee: function (ident, sync, iterable) { 1.369 + sync.pos[ident] = -1; 1.370 + var m = MochiKit.Base; 1.371 + var listMin = m.listMin; 1.372 + return { 1.373 + repr: function () { return "tee(" + ident + ", ...)"; }, 1.374 + toString: m.forwardCall("repr"), 1.375 + next: function () { 1.376 + var rval; 1.377 + var i = sync.pos[ident]; 1.378 + 1.379 + if (i == sync.max) { 1.380 + rval = iterable.next(); 1.381 + sync.deque.push(rval); 1.382 + sync.max += 1; 1.383 + sync.pos[ident] += 1; 1.384 + } else { 1.385 + rval = sync.deque[i - sync.min]; 1.386 + sync.pos[ident] += 1; 1.387 + if (i == sync.min && listMin(sync.pos) != sync.min) { 1.388 + sync.min += 1; 1.389 + sync.deque.shift(); 1.390 + } 1.391 + } 1.392 + return rval; 1.393 + } 1.394 + }; 1.395 + }, 1.396 + 1.397 + /** @id MochiKit.Iter.tee */ 1.398 + tee: function (iterable, n/* = 2 */) { 1.399 + var rval = []; 1.400 + var sync = { 1.401 + "pos": [], 1.402 + "deque": [], 1.403 + "max": -1, 1.404 + "min": -1 1.405 + }; 1.406 + if (arguments.length == 1 || typeof(n) == "undefined" || n === null) { 1.407 + n = 2; 1.408 + } 1.409 + var self = MochiKit.Iter; 1.410 + iterable = self.iter(iterable); 1.411 + var _tee = self._tee; 1.412 + for (var i = 0; i < n; i++) { 1.413 + rval.push(_tee(i, sync, iterable)); 1.414 + } 1.415 + return rval; 1.416 + }, 1.417 + 1.418 + /** @id MochiKit.Iter.list */ 1.419 + list: function (iterable) { 1.420 + // Fast-path for Array and Array-like 1.421 + var m = MochiKit.Base; 1.422 + if (typeof(iterable.slice) == 'function') { 1.423 + return iterable.slice(); 1.424 + } else if (m.isArrayLike(iterable)) { 1.425 + return m.concat(iterable); 1.426 + } 1.427 + 1.428 + var self = MochiKit.Iter; 1.429 + iterable = self.iter(iterable); 1.430 + var rval = []; 1.431 + try { 1.432 + while (true) { 1.433 + rval.push(iterable.next()); 1.434 + } 1.435 + } catch (e) { 1.436 + if (e != self.StopIteration) { 1.437 + throw e; 1.438 + } 1.439 + return rval; 1.440 + } 1.441 + // mozilla warnings aren't too bright 1.442 + return undefined; 1.443 + }, 1.444 + 1.445 + 1.446 + /** @id MochiKit.Iter.reduce */ 1.447 + reduce: function (fn, iterable, /* optional */initial) { 1.448 + var i = 0; 1.449 + var x = initial; 1.450 + var self = MochiKit.Iter; 1.451 + iterable = self.iter(iterable); 1.452 + if (arguments.length < 3) { 1.453 + try { 1.454 + x = iterable.next(); 1.455 + } catch (e) { 1.456 + if (e == self.StopIteration) { 1.457 + e = new TypeError("reduce() of empty sequence with no initial value"); 1.458 + } 1.459 + throw e; 1.460 + } 1.461 + i++; 1.462 + } 1.463 + try { 1.464 + while (true) { 1.465 + x = fn(x, iterable.next()); 1.466 + } 1.467 + } catch (e) { 1.468 + if (e != self.StopIteration) { 1.469 + throw e; 1.470 + } 1.471 + } 1.472 + return x; 1.473 + }, 1.474 + 1.475 + /** @id MochiKit.Iter.range */ 1.476 + range: function (/* [start,] stop[, step] */) { 1.477 + var start = 0; 1.478 + var stop = 0; 1.479 + var step = 1; 1.480 + if (arguments.length == 1) { 1.481 + stop = arguments[0]; 1.482 + } else if (arguments.length == 2) { 1.483 + start = arguments[0]; 1.484 + stop = arguments[1]; 1.485 + } else if (arguments.length == 3) { 1.486 + start = arguments[0]; 1.487 + stop = arguments[1]; 1.488 + step = arguments[2]; 1.489 + } else { 1.490 + throw new TypeError("range() takes 1, 2, or 3 arguments!"); 1.491 + } 1.492 + if (step === 0) { 1.493 + throw new TypeError("range() step must not be 0"); 1.494 + } 1.495 + return { 1.496 + next: function () { 1.497 + if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) { 1.498 + throw MochiKit.Iter.StopIteration; 1.499 + } 1.500 + var rval = start; 1.501 + start += step; 1.502 + return rval; 1.503 + }, 1.504 + repr: function () { 1.505 + return "range(" + [start, stop, step].join(", ") + ")"; 1.506 + }, 1.507 + toString: MochiKit.Base.forwardCall("repr") 1.508 + }; 1.509 + }, 1.510 + 1.511 + /** @id MochiKit.Iter.sum */ 1.512 + sum: function (iterable, start/* = 0 */) { 1.513 + if (typeof(start) == "undefined" || start === null) { 1.514 + start = 0; 1.515 + } 1.516 + var x = start; 1.517 + var self = MochiKit.Iter; 1.518 + iterable = self.iter(iterable); 1.519 + try { 1.520 + while (true) { 1.521 + x += iterable.next(); 1.522 + } 1.523 + } catch (e) { 1.524 + if (e != self.StopIteration) { 1.525 + throw e; 1.526 + } 1.527 + } 1.528 + return x; 1.529 + }, 1.530 + 1.531 + /** @id MochiKit.Iter.exhaust */ 1.532 + exhaust: function (iterable) { 1.533 + var self = MochiKit.Iter; 1.534 + iterable = self.iter(iterable); 1.535 + try { 1.536 + while (true) { 1.537 + iterable.next(); 1.538 + } 1.539 + } catch (e) { 1.540 + if (e != self.StopIteration) { 1.541 + throw e; 1.542 + } 1.543 + } 1.544 + }, 1.545 + 1.546 + /** @id MochiKit.Iter.forEach */ 1.547 + forEach: function (iterable, func, /* optional */self) { 1.548 + var m = MochiKit.Base; 1.549 + if (arguments.length > 2) { 1.550 + func = m.bind(func, self); 1.551 + } 1.552 + // fast path for array 1.553 + if (m.isArrayLike(iterable)) { 1.554 + try { 1.555 + for (var i = 0; i < iterable.length; i++) { 1.556 + func(iterable[i]); 1.557 + } 1.558 + } catch (e) { 1.559 + if (e != MochiKit.Iter.StopIteration) { 1.560 + throw e; 1.561 + } 1.562 + } 1.563 + } else { 1.564 + self = MochiKit.Iter; 1.565 + self.exhaust(self.imap(func, iterable)); 1.566 + } 1.567 + }, 1.568 + 1.569 + /** @id MochiKit.Iter.every */ 1.570 + every: function (iterable, func) { 1.571 + var self = MochiKit.Iter; 1.572 + try { 1.573 + self.ifilterfalse(func, iterable).next(); 1.574 + return false; 1.575 + } catch (e) { 1.576 + if (e != self.StopIteration) { 1.577 + throw e; 1.578 + } 1.579 + return true; 1.580 + } 1.581 + }, 1.582 + 1.583 + /** @id MochiKit.Iter.sorted */ 1.584 + sorted: function (iterable, /* optional */cmp) { 1.585 + var rval = MochiKit.Iter.list(iterable); 1.586 + if (arguments.length == 1) { 1.587 + cmp = MochiKit.Base.compare; 1.588 + } 1.589 + rval.sort(cmp); 1.590 + return rval; 1.591 + }, 1.592 + 1.593 + /** @id MochiKit.Iter.reversed */ 1.594 + reversed: function (iterable) { 1.595 + var rval = MochiKit.Iter.list(iterable); 1.596 + rval.reverse(); 1.597 + return rval; 1.598 + }, 1.599 + 1.600 + /** @id MochiKit.Iter.some */ 1.601 + some: function (iterable, func) { 1.602 + var self = MochiKit.Iter; 1.603 + try { 1.604 + self.ifilter(func, iterable).next(); 1.605 + return true; 1.606 + } catch (e) { 1.607 + if (e != self.StopIteration) { 1.608 + throw e; 1.609 + } 1.610 + return false; 1.611 + } 1.612 + }, 1.613 + 1.614 + /** @id MochiKit.Iter.iextend */ 1.615 + iextend: function (lst, iterable) { 1.616 + if (MochiKit.Base.isArrayLike(iterable)) { 1.617 + // fast-path for array-like 1.618 + for (var i = 0; i < iterable.length; i++) { 1.619 + lst.push(iterable[i]); 1.620 + } 1.621 + } else { 1.622 + var self = MochiKit.Iter; 1.623 + iterable = self.iter(iterable); 1.624 + try { 1.625 + while (true) { 1.626 + lst.push(iterable.next()); 1.627 + } 1.628 + } catch (e) { 1.629 + if (e != self.StopIteration) { 1.630 + throw e; 1.631 + } 1.632 + } 1.633 + } 1.634 + return lst; 1.635 + }, 1.636 + 1.637 + /** @id MochiKit.Iter.groupby */ 1.638 + groupby: function(iterable, /* optional */ keyfunc) { 1.639 + var m = MochiKit.Base; 1.640 + var self = MochiKit.Iter; 1.641 + if (arguments.length < 2) { 1.642 + keyfunc = m.operator.identity; 1.643 + } 1.644 + iterable = self.iter(iterable); 1.645 + 1.646 + // shared 1.647 + var pk = undefined; 1.648 + var k = undefined; 1.649 + var v; 1.650 + 1.651 + function fetch() { 1.652 + v = iterable.next(); 1.653 + k = keyfunc(v); 1.654 + }; 1.655 + 1.656 + function eat() { 1.657 + var ret = v; 1.658 + v = undefined; 1.659 + return ret; 1.660 + }; 1.661 + 1.662 + var first = true; 1.663 + var compare = m.compare; 1.664 + return { 1.665 + repr: function () { return "groupby(...)"; }, 1.666 + next: function() { 1.667 + // iterator-next 1.668 + 1.669 + // iterate until meet next group 1.670 + while (compare(k, pk) === 0) { 1.671 + fetch(); 1.672 + if (first) { 1.673 + first = false; 1.674 + break; 1.675 + } 1.676 + } 1.677 + pk = k; 1.678 + return [k, { 1.679 + next: function() { 1.680 + // subiterator-next 1.681 + if (v == undefined) { // Is there something to eat? 1.682 + fetch(); 1.683 + } 1.684 + if (compare(k, pk) !== 0) { 1.685 + throw self.StopIteration; 1.686 + } 1.687 + return eat(); 1.688 + } 1.689 + }]; 1.690 + } 1.691 + }; 1.692 + }, 1.693 + 1.694 + /** @id MochiKit.Iter.groupby_as_array */ 1.695 + groupby_as_array: function (iterable, /* optional */ keyfunc) { 1.696 + var m = MochiKit.Base; 1.697 + var self = MochiKit.Iter; 1.698 + if (arguments.length < 2) { 1.699 + keyfunc = m.operator.identity; 1.700 + } 1.701 + 1.702 + iterable = self.iter(iterable); 1.703 + var result = []; 1.704 + var first = true; 1.705 + var prev_key; 1.706 + var compare = m.compare; 1.707 + while (true) { 1.708 + try { 1.709 + var value = iterable.next(); 1.710 + var key = keyfunc(value); 1.711 + } catch (e) { 1.712 + if (e == self.StopIteration) { 1.713 + break; 1.714 + } 1.715 + throw e; 1.716 + } 1.717 + if (first || compare(key, prev_key) !== 0) { 1.718 + var values = []; 1.719 + result.push([key, values]); 1.720 + } 1.721 + values.push(value); 1.722 + first = false; 1.723 + prev_key = key; 1.724 + } 1.725 + return result; 1.726 + }, 1.727 + 1.728 + /** @id MochiKit.Iter.arrayLikeIter */ 1.729 + arrayLikeIter: function (iterable) { 1.730 + var i = 0; 1.731 + return { 1.732 + repr: function () { return "arrayLikeIter(...)"; }, 1.733 + toString: MochiKit.Base.forwardCall("repr"), 1.734 + next: function () { 1.735 + if (i >= iterable.length) { 1.736 + throw MochiKit.Iter.StopIteration; 1.737 + } 1.738 + return iterable[i++]; 1.739 + } 1.740 + }; 1.741 + }, 1.742 + 1.743 + /** @id MochiKit.Iter.hasIterateNext */ 1.744 + hasIterateNext: function (iterable) { 1.745 + return (iterable && typeof(iterable.iterateNext) == "function"); 1.746 + }, 1.747 + 1.748 + /** @id MochiKit.Iter.iterateNextIter */ 1.749 + iterateNextIter: function (iterable) { 1.750 + return { 1.751 + repr: function () { return "iterateNextIter(...)"; }, 1.752 + toString: MochiKit.Base.forwardCall("repr"), 1.753 + next: function () { 1.754 + var rval = iterable.iterateNext(); 1.755 + if (rval === null || rval === undefined) { 1.756 + throw MochiKit.Iter.StopIteration; 1.757 + } 1.758 + return rval; 1.759 + } 1.760 + }; 1.761 + } 1.762 +}); 1.763 + 1.764 + 1.765 +MochiKit.Iter.EXPORT_OK = [ 1.766 + "iteratorRegistry", 1.767 + "arrayLikeIter", 1.768 + "hasIterateNext", 1.769 + "iterateNextIter", 1.770 +]; 1.771 + 1.772 +MochiKit.Iter.EXPORT = [ 1.773 + "StopIteration", 1.774 + "registerIteratorFactory", 1.775 + "iter", 1.776 + "count", 1.777 + "cycle", 1.778 + "repeat", 1.779 + "next", 1.780 + "izip", 1.781 + "ifilter", 1.782 + "ifilterfalse", 1.783 + "islice", 1.784 + "imap", 1.785 + "applymap", 1.786 + "chain", 1.787 + "takewhile", 1.788 + "dropwhile", 1.789 + "tee", 1.790 + "list", 1.791 + "reduce", 1.792 + "range", 1.793 + "sum", 1.794 + "exhaust", 1.795 + "forEach", 1.796 + "every", 1.797 + "sorted", 1.798 + "reversed", 1.799 + "some", 1.800 + "iextend", 1.801 + "groupby", 1.802 + "groupby_as_array" 1.803 +]; 1.804 + 1.805 +MochiKit.Iter.__new__ = function () { 1.806 + var m = MochiKit.Base; 1.807 + // Re-use StopIteration if exists (e.g. SpiderMonkey) 1.808 + if (typeof(StopIteration) != "undefined") { 1.809 + this.StopIteration = StopIteration; 1.810 + } else { 1.811 + /** @id MochiKit.Iter.StopIteration */ 1.812 + this.StopIteration = new m.NamedError("StopIteration"); 1.813 + } 1.814 + this.iteratorRegistry = new m.AdapterRegistry(); 1.815 + // Register the iterator factory for arrays 1.816 + this.registerIteratorFactory( 1.817 + "arrayLike", 1.818 + m.isArrayLike, 1.819 + this.arrayLikeIter 1.820 + ); 1.821 + 1.822 + this.registerIteratorFactory( 1.823 + "iterateNext", 1.824 + this.hasIterateNext, 1.825 + this.iterateNextIter 1.826 + ); 1.827 + 1.828 + this.EXPORT_TAGS = { 1.829 + ":common": this.EXPORT, 1.830 + ":all": m.concat(this.EXPORT, this.EXPORT_OK) 1.831 + }; 1.832 + 1.833 + m.nameFunctions(this); 1.834 + 1.835 +}; 1.836 + 1.837 +MochiKit.Iter.__new__(); 1.838 + 1.839 +// 1.840 +// XXX: Internet Explorer blows 1.841 +// 1.842 +if (MochiKit.__export__) { 1.843 + reduce = MochiKit.Iter.reduce; 1.844 +} 1.845 + 1.846 +MochiKit.Base._exportSymbols(this, MochiKit.Iter);