Initial check-in
[dygraphs.git] / mochikit_v14 / doc / rst / MochiKit / Iter.rst
1 .. title:: MochiKit.Iter - itertools for JavaScript; iteration made HARD, and then easy
2
3 Name
4 ====
5
6 MochiKit.Iter - itertools for JavaScript; iteration made HARD, and
7 then easy
8
9
10 Synopsis
11 ========
12
13 ::
14
15
16     theSum = sum(takewhile(
17             partial(operator.gt, 10),
18             imap(
19                 partial(operator.mul, 2),
20                 count()
21             )
22         )
23     ));
24
25     assert( theSum == (0 + 0 + 2 + 4 + 6 + 8) );
26
27
28 Description
29 ===========
30
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]_.
35
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
42 the result is not.
43
44
45 Dependencies
46 ============
47
48 - :mochiref:`MochiKit.Base`
49
50
51 Overview
52 ========
53
54 Iteration for JavaScript
55 ------------------------
56
57 The best overview right now is in my Iteration for JavaScript [3]_
58 blog entry.  This information will migrate here eventually.
59
60 API Reference
61 =============
62
63 Errors
64 ------
65
66 :mochidef:`StopIteration`:
67
68     The singleton :mochiref:`MochiKit.Base.NamedError` that signifies
69     the end of an iterator
70
71     *Availability*:
72         Available in MochiKit 1.3.1+
73
74
75 Functions
76 ---------
77
78 :mochidef:`applymap(fun, seq[, self])`:
79
80     ``applymap(fun, seq)`` -->
81     fun.apply(self, seq0), fun.apply(self, seq1), ...
82
83     *Availability*:
84         Available in MochiKit 1.3.1+
85
86
87 :mochidef:`chain(p, q[, ...])`:
88
89     ``chain(p, q, ...)`` --> p0, p1, ... plast, q0, q1, ...
90
91     *Availability*:
92         Available in MochiKit 1.3.1+
93
94
95 :mochidef:`count(n=0)`:
96
97     ``count(n=0)`` --> n, n + 1, n + 2, ...
98
99     *Availability*:
100         Available in MochiKit 1.3.1+
101
102
103 :mochidef:`cycle(p)`:
104
105     ``cycle(p)`` --> p0, p1, ... plast, p0, p1, ...
106
107     *Availability*:
108         Available in MochiKit 1.3.1+
109
110
111 :mochidef:`dropwhile(pred, seq)`:
112
113     ``dropwhile(pred, seq)`` --> seq[n], seq[n + 1], starting when
114     pred(seq[n]) fails
115
116     *Availability*:
117         Available in MochiKit 1.3.1+
118
119
120 :mochidef:`every(iterable, func)`:
121
122     Return ``true`` if ``func(item)`` is ``true`` for every item in
123     ``iterable``.
124
125     *Availability*:
126         Available in MochiKit 1.3.1+
127
128
129 :mochidef:`exhaust(iterable)`:
130
131     Exhausts an iterable without saving the results anywhere, like
132     :mochiref:`list(iterable)` when you don't care what the output is.
133
134     *Availability*:
135         Available in MochiKit 1.3.1+
136
137
138 :mochidef:`forEach(iterable, func[, self])`:
139
140     Call ``func`` for each item in ``iterable``, and don't save the
141     results.
142
143     *Availability*:
144         Available in MochiKit 1.3.1+
145
146
147 :mochidef:`groupby(iterable[, keyfunc])`:
148
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.
154
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::
160
161         var groups = [];
162         var uniquekeys = [];
163         forEach(groupby(data, keyfunc), function (key_group) {
164             groups.push(list(key_group[1]));
165             uniquekeys.push(key_group[0]);
166         });
167
168     As a convenience, :mochiref:`groupby_as_array()` is provided to
169     suit the above use case.
170
171     *Availability*:
172         Available in MochiKit 1.3.1+
173
174
175 :mochidef:`groupby_as_array(iterable[, keyfunc])`:
176
177     Perform the same task as :mochiref:`groupby()`, except return an
178     array of arrays instead of an iterator of iterators.
179
180     *Availability*:
181         Available in MochiKit 1.3.1+
182
183
184 :mochidef:`iextend(lst, iterable)`:
185
186     Just like :mochiref:`list(iterable)`, except it pushes results on
187     ``lst`` rather than creating a new one.
188
189     *Availability*:
190         Available in MochiKit 1.3.1+
191
192
193 :mochidef:`ifilter(pred, seq)`:
194
195     ``ifilter(pred, seq)`` --> elements of seq where ``pred(elem)`` is
196     ``true``
197
198     *Availability*:
199         Available in MochiKit 1.3.1+
200
201
202 :mochidef:`ifilterfalse(pred, seq)`:
203
204     ``ifilterfalse(pred, seq)`` --> elements of seq where
205     ``pred(elem)`` is ``false``
206
207     *Availability*:
208         Available in MochiKit 1.3.1+
209
210
211 :mochidef:`imap(fun, p, q[, ...])`:
212
213     ``imap(fun, p, q, ...)`` --> fun(p0, q0, ...), fun(p1, q1, ...),
214     ...
215
216     *Availability*:
217         Available in MochiKit 1.3.1+
218
219
220 :mochidef:`islice(seq, [start,] stop[, step])`:
221
222     ``islice(seq, [start,] stop[, step])`` --> elements from
223     seq[start:stop:step] (in Python slice syntax)
224
225     *Availability*:
226         Available in MochiKit 1.3.1+
227
228
229 :mochidef:`iter(iterable[, sentinel])`:
230
231     Convert the given argument to an iterator (object implementing
232     ``.next()``).
233
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
238        returned.
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
244        match.
245     5. If no factory is found, it will throw ``TypeError``
246
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``).
250
251     When used directly, using an iterator should look like this::
252
253         var it = iter(iterable);
254         try {
255             while (var o = it.next()) {
256                 // use o
257             }
258         } catch (e) {
259             if (e != StopIteration) {
260                 throw e;
261             }
262             // pass
263         }
264
265     This is ugly, so you should use the higher order functions to work
266     with iterators whenever possible.
267
268     *Availability*:
269         Available in MochiKit 1.3.1+
270
271
272 :mochidef:`izip(p, q[, ...])`:
273
274     ``izip(p, q, ...)`` --> [p0, q0, ...], [p1, q1, ...], ...
275
276     *Availability*:
277         Available in MochiKit 1.3.1+
278
279
280 :mochidef:`list(iterable)`:
281
282     Convert ``iterable`` to a new ``Array``
283
284     *Availability*:
285         Available in MochiKit 1.3.1+
286
287
288 :mochidef:`next(iterator)`:
289
290     Return ``iterator.next()``
291
292     *Availability*:
293         Available in MochiKit 1.3.1+
294
295
296 :mochidef:`range([start,] stop[, step])`:
297
298     Return an iterator containing an arithmetic progression of integers.
299
300     ``range(i, j)`` returns :mochiref:`iter([i, i + 1, i + 2, ..., j -
301     1])`
302
303     ``start`` (!) defaults to ``0``. When ``step`` is given, it
304     specifies the increment (or decrement). The end point is omitted!
305
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
308     elements.
309
310     *Availability*:
311         Available in MochiKit 1.3.1+
312
313
314 :mochidef:`reduce(fn, iterable[, initial])`:
315
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.
318
319     For example::
320
321         reduce(function (a, b) { return x + y; }, [1, 2, 3, 4, 5])
322
323     calculates::
324
325         ((((1 + 2) + 3) + 4) + 5).
326
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
329     empty.
330
331     Note that the above example could be written more clearly as::
332
333         reduce(operator.add, [1, 2, 3, 4, 5])
334
335     Or even simpler::
336
337         sum([1, 2, 3, 4, 5])
338
339     *Availability*:
340         Available in MochiKit 1.3.1+
341
342
343 :mochidef:`registerIteratorFactory(name, check, iterfactory[, override])`:
344
345     Register an iterator factory for use with the iter function.
346
347     ``check`` is a ``function(a)`` that returns ``true`` if ``a`` can
348     be converted into an iterator with ``iterfactory``.
349
350     ``iterfactory`` is a ``function(a)`` that returns an object with a
351     ``.next()`` method that returns the next value in the sequence.
352
353     ``iterfactory`` is guaranteed to only be called if ``check(a)``
354     returns a true value.
355
356     If ``override`` is ``true``, then it will be made the
357     highest precedence iterator factory. Otherwise, the lowest.
358
359     *Availability*:
360         Available in MochiKit 1.3.1+
361
362
363 :mochidef:`repeat(elem[, n])`:
364
365     ``repeat(elem, [,n])`` --> elem, elem, elem, ... endlessly or up
366     to n times
367
368     *Availability*:
369         Available in MochiKit 1.3.1+
370
371
372 :mochidef:`reversed(iterable)`:
373
374     Return a reversed array from iterable.
375
376     *Availability*:
377         Available in MochiKit 1.3.1+
378
379
380 :mochidef:`some(iterable, func)`:
381
382     Return ``true`` if ``func(item)`` is ``true`` for at least one
383     item in ``iterable``.
384
385     *Availability*:
386         Available in MochiKit 1.3.1+
387
388
389 :mochidef:`sorted(iterable[, cmp])`:
390
391     Return a sorted array from iterable.
392
393     *Availability*:
394         Available in MochiKit 1.3.1+
395
396
397 :mochidef:`sum(iterable, start=0)`:
398
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.
402
403     Equivalent to::
404
405         reduce(operator.add, iterable, start);
406
407     *Availability*:
408         Available in MochiKit 1.3.1+
409
410
411 :mochidef:`takewhile(pred, seq)`:
412
413     ``takewhile(pred, seq)`` --> seq[0], seq[1], ... until
414     pred(seq[n]) fails
415
416     *Availability*:
417         Available in MochiKit 1.3.1+
418
419
420 :mochidef:`tee(iterable, n=2)`:
421
422     ``tee(it, n=2)`` --> [it1, it2, it3, ... itn] splits one iterator
423     into n
424
425     *Availability*:
426         Available in MochiKit 1.3.1+
427
428
429 See Also
430 ========
431
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/
437
438
439 Authors
440 =======
441
442 - Bob Ippolito <bob@redivi.com>
443
444
445 Copyright
446 =========
447
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
451 v2.1`_.
452
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