1 .. title:: MochiKit.Iter - itertools for JavaScript; iteration made HARD, and then easy
6 MochiKit.Iter - itertools for JavaScript; iteration made HARD, and
16 theSum = sum(takewhile(
17 partial(operator.gt, 10),
19 partial(operator.mul, 2),
25 assert( theSum == (0 + 0 + 2 + 4 + 6 + 8) );
31 All of the functional programming missing from
32 :mochiref:`MochiKit.Base` lives here. The functionality in this module
33 is largely inspired by Python's iteration protocol [1]_, and the
34 itertools module [2]_.
36 MochiKit.Iter defines a standard way to iterate over anything, that
37 you can extend with :mochiref:`registerIterator`, or by implementing
38 the ``.iter()`` or ``.__iterator__()`` (in MochiKit 1.4+) protocol.
39 Iterators are lazy, so it can potentially be
40 cheaper to build a filter chain of iterators than to build lots of
41 intermediate arrays. Especially when the data set is very large, but
48 - :mochiref:`MochiKit.Base`
54 Iteration for JavaScript
55 ------------------------
57 The best overview right now is in my Iteration for JavaScript [3]_
58 blog entry. This information will migrate here eventually.
66 :mochidef:`StopIteration`:
68 The singleton :mochiref:`MochiKit.Base.NamedError` that signifies
69 the end of an iterator
72 Available in MochiKit 1.3.1+
78 :mochidef:`applymap(fun, seq[, self])`:
80 ``applymap(fun, seq)`` -->
81 fun.apply(self, seq0), fun.apply(self, seq1), ...
84 Available in MochiKit 1.3.1+
87 :mochidef:`chain(p, q[, ...])`:
89 ``chain(p, q, ...)`` --> p0, p1, ... plast, q0, q1, ...
92 Available in MochiKit 1.3.1+
95 :mochidef:`count(n=0)`:
97 ``count(n=0)`` --> n, n + 1, n + 2, ...
100 Available in MochiKit 1.3.1+
103 :mochidef:`cycle(p)`:
105 ``cycle(p)`` --> p0, p1, ... plast, p0, p1, ...
108 Available in MochiKit 1.3.1+
111 :mochidef:`dropwhile(pred, seq)`:
113 ``dropwhile(pred, seq)`` --> seq[n], seq[n + 1], starting when
117 Available in MochiKit 1.3.1+
120 :mochidef:`every(iterable, func)`:
122 Return ``true`` if ``func(item)`` is ``true`` for every item in
126 Available in MochiKit 1.3.1+
129 :mochidef:`exhaust(iterable)`:
131 Exhausts an iterable without saving the results anywhere, like
132 :mochiref:`list(iterable)` when you don't care what the output is.
135 Available in MochiKit 1.3.1+
138 :mochidef:`forEach(iterable, func[, self])`:
140 Call ``func`` for each item in ``iterable``, and don't save the
144 Available in MochiKit 1.3.1+
147 :mochidef:`groupby(iterable[, keyfunc])`:
149 Make an iterator that returns consecutive keys and groups from the
150 iterable. The key is a function computing a key value for each
151 element. If not specified or is None, key defaults to an identity
152 function and returns the element unchanged. Generally, the
153 iterable needs to already be sorted on the same key function.
155 The returned group is itself an iterator that shares the
156 underlying iterable with :mochiref:`groupby()`. Because the source
157 is shared, when the groupby object is advanced, the previous group
158 is no longer visible. So, if that data is needed later, it should
159 be stored as an array::
163 forEach(groupby(data, keyfunc), function (key_group) {
164 groups.push(list(key_group[1]));
165 uniquekeys.push(key_group[0]);
168 As a convenience, :mochiref:`groupby_as_array()` is provided to
169 suit the above use case.
172 Available in MochiKit 1.3.1+
175 :mochidef:`groupby_as_array(iterable[, keyfunc])`:
177 Perform the same task as :mochiref:`groupby()`, except return an
178 array of arrays instead of an iterator of iterators.
181 Available in MochiKit 1.3.1+
184 :mochidef:`iextend(lst, iterable)`:
186 Just like :mochiref:`list(iterable)`, except it pushes results on
187 ``lst`` rather than creating a new one.
190 Available in MochiKit 1.3.1+
193 :mochidef:`ifilter(pred, seq)`:
195 ``ifilter(pred, seq)`` --> elements of seq where ``pred(elem)`` is
199 Available in MochiKit 1.3.1+
202 :mochidef:`ifilterfalse(pred, seq)`:
204 ``ifilterfalse(pred, seq)`` --> elements of seq where
205 ``pred(elem)`` is ``false``
208 Available in MochiKit 1.3.1+
211 :mochidef:`imap(fun, p, q[, ...])`:
213 ``imap(fun, p, q, ...)`` --> fun(p0, q0, ...), fun(p1, q1, ...),
217 Available in MochiKit 1.3.1+
220 :mochidef:`islice(seq, [start,] stop[, step])`:
222 ``islice(seq, [start,] stop[, step])`` --> elements from
223 seq[start:stop:step] (in Python slice syntax)
226 Available in MochiKit 1.3.1+
229 :mochidef:`iter(iterable[, sentinel])`:
231 Convert the given argument to an iterator (object implementing
234 1. If ``iterable`` is an iterator (implements ``.next()``), then
235 it will be returned as-is.
236 2. If ``iterable`` is an iterator factory (implements
237 ``.iter()``), then the result of ``iterable.iter()`` will be
239 3. If ``iterable`` is a JavaScript 1.7 iterator factory (implements
240 ``.__iterable__()``), then the result of ``iterable.__iterable__()``
241 will be returned (MochiKit 1.4+).
242 4. Otherwise, the iterator factory
243 :mochiref:`MochiKit.Base.AdapterRegistry` is used to find a
245 5. If no factory is found, it will throw ``TypeError``
247 Built-in iterator factories are present for Array-like objects,
248 and objects that implement the ``iterateNext`` protocol (e.g. the
249 result of Mozilla's ``document.evaluate``).
251 When used directly, using an iterator should look like this::
253 var it = iter(iterable);
255 while (var o = it.next()) {
259 if (e != StopIteration) {
265 This is ugly, so you should use the higher order functions to work
266 with iterators whenever possible.
269 Available in MochiKit 1.3.1+
272 :mochidef:`izip(p, q[, ...])`:
274 ``izip(p, q, ...)`` --> [p0, q0, ...], [p1, q1, ...], ...
277 Available in MochiKit 1.3.1+
280 :mochidef:`list(iterable)`:
282 Convert ``iterable`` to a new ``Array``
285 Available in MochiKit 1.3.1+
288 :mochidef:`next(iterator)`:
290 Return ``iterator.next()``
293 Available in MochiKit 1.3.1+
296 :mochidef:`range([start,] stop[, step])`:
298 Return an iterator containing an arithmetic progression of integers.
300 ``range(i, j)`` returns :mochiref:`iter([i, i + 1, i + 2, ..., j -
303 ``start`` (!) defaults to ``0``. When ``step`` is given, it
304 specifies the increment (or decrement). The end point is omitted!
306 For example, ``range(4)`` returns :mochiref:`iter([0, 1, 2, 3])`.
307 This iterates over exactly the valid indexes for an array of 4
311 Available in MochiKit 1.3.1+
314 :mochidef:`reduce(fn, iterable[, initial])`:
316 Apply ``fn(a, b)`` cumulatively to the items of an iterable from
317 left to right, so as to reduce the iterable to a single value.
321 reduce(function (a, b) { return x + y; }, [1, 2, 3, 4, 5])
325 ((((1 + 2) + 3) + 4) + 5).
327 If initial is given, it is placed before the items of the sequence
328 in the calculation, and serves as a default when the sequence is
331 Note that the above example could be written more clearly as::
333 reduce(operator.add, [1, 2, 3, 4, 5])
340 Available in MochiKit 1.3.1+
343 :mochidef:`registerIteratorFactory(name, check, iterfactory[, override])`:
345 Register an iterator factory for use with the iter function.
347 ``check`` is a ``function(a)`` that returns ``true`` if ``a`` can
348 be converted into an iterator with ``iterfactory``.
350 ``iterfactory`` is a ``function(a)`` that returns an object with a
351 ``.next()`` method that returns the next value in the sequence.
353 ``iterfactory`` is guaranteed to only be called if ``check(a)``
354 returns a true value.
356 If ``override`` is ``true``, then it will be made the
357 highest precedence iterator factory. Otherwise, the lowest.
360 Available in MochiKit 1.3.1+
363 :mochidef:`repeat(elem[, n])`:
365 ``repeat(elem, [,n])`` --> elem, elem, elem, ... endlessly or up
369 Available in MochiKit 1.3.1+
372 :mochidef:`reversed(iterable)`:
374 Return a reversed array from iterable.
377 Available in MochiKit 1.3.1+
380 :mochidef:`some(iterable, func)`:
382 Return ``true`` if ``func(item)`` is ``true`` for at least one
383 item in ``iterable``.
386 Available in MochiKit 1.3.1+
389 :mochidef:`sorted(iterable[, cmp])`:
391 Return a sorted array from iterable.
394 Available in MochiKit 1.3.1+
397 :mochidef:`sum(iterable, start=0)`:
399 Returns the sum of a sequence of numbers plus the value of
400 parameter ``start`` (with a default of 0). When the sequence is
401 empty, returns start.
405 reduce(operator.add, iterable, start);
408 Available in MochiKit 1.3.1+
411 :mochidef:`takewhile(pred, seq)`:
413 ``takewhile(pred, seq)`` --> seq[0], seq[1], ... until
417 Available in MochiKit 1.3.1+
420 :mochidef:`tee(iterable, n=2)`:
422 ``tee(it, n=2)`` --> [it1, it2, it3, ... itn] splits one iterator
426 Available in MochiKit 1.3.1+
432 .. [1] The iteration protocol is described in
433 PEP 234 - Iterators: http://www.python.org/peps/pep-0234.html
434 .. [2] Python's itertools
435 module: http://docs.python.org/lib/module-itertools.html
436 .. [3] Iteration in JavaScript: http://bob.pythonmac.org/archives/2005/07/06/iteration-in-javascript/
442 - Bob Ippolito <bob@redivi.com>
448 Copyright 2005 Bob Ippolito <bob@redivi.com>. This program is
449 dual-licensed free software; you can redistribute it and/or modify it
450 under the terms of the `MIT License`_ or the `Academic Free License
453 .. _`MIT License`: http://www.opensource.org/licenses/mit-license.php
454 .. _`Academic Free License v2.1`: http://www.opensource.org/licenses/afl-2.1.php