Français - English
Source (plain): svn://svn.saintamh.org/code/lib-js/trunk/saintamh/iterator.js
Source (highlighted): http://svn.saintamh.org/code/lib-js/trunk/saintamh/iterator.js

This library implements a unified iterator framework for JavaScript. It aims to provide something approaching the funcionality of the Scala Seq class, or of Python iterators.

 

It places one symbol, I, in the global namespace. When called as a function, it will create an iterator out of any iterable value:

    var i0 = I([1,2,3]); // from an Array object
    var i1 = I("A bright cold day in April"); // from a string
    var i2 = I(document.getElementsByTagName('a')); // from any array-like object

There are also utilities for creating iterators from other sources:

    // i3 will contain the matching substrings
    var i3 = I.matches (/\w+/, "Ipsum lorem dolor sit amet");

    // I.split(re,str) is equivalent to I(str.split(re))
    var i4 = I.split (/\s+/, "Ipsum lorem dolor sit amet");

    // Iterate over any object's keys, values, or key/value pairs:
    var i5 = I.keys ({a: 1, b: 2});
    var i6 = I.values ({a: 1, b: 2});
    var i7 = I.items ({a: 1, b: 2});

    // Arbitrary integer range. Like all iterators, the range is evaluated
    // lazily -- the full list is never all held in memory at once
    var i8 = I.range (0, 1000*1000);

    // "concatenate" several iterables
    var i9 = I.chain (i0, [4,5,6], '789');

 

All iterators share the same interface. The basic functionality is provided by two methods, named after their java.util.Iterator counterparts:

You should probably never have to call these explicitly, though, unless you're implementing an extension to the framework itself.

 

All iterators also have several methods that allow manupilation, combination, transformation and reduction of iterator streams:

    // Iterate on an Array's values without having to use indices.
    I(anyArray).foreach (function (elem) {
        doSomethingWith(elem);
    });

    // returns "0-1-4-64-81"
    I.range(10).
        map (function (n) { return n*n }).
        grep (function (n) { return n%10 < 5 }).
        join ('-');

    // If for some reason you wanted to re-implement boolean operators:
    function AND () {
        return I(arguments).
            map (I.nvoke()).
            all();
    }

    // Note that the above is correctly short-circuited, i.e. the following
    // returns false and throws no exception:
    AND (
        function () { return false; },
        function () { throw "Huh?"; }
    );

 

Each of the higher-order methods has a "splat" counterpart, with the same name but suffixed with a $ sign, meant for use with iterators whose elements are arrays (e.g. 2D arrays). The function passed as argument will be called for each subarray, with the subarray expanded as the function's arguments.

    // Iterate over an array and its indices
    I(anyArray).enumerate().foreach$ (function (i, elem) {
        print ("Elem at position " + i + " is " + elem);
    });

 

There are many more utilities available -- have a look at the source code for all the details. There's also a somewhat readable unit tests suite, that may be insightful.