View on GitHub

IterizerJs

Expressive & concise code using ES6 iterables

Download this project as a .zip file Download this project as a tar.gz file

IterizerJs makes it easier to write code that makes extensive use of ES6 iterables. Banish the arcane C-style for loop, and write cleaner, more expressive and concise code instead.

Why you might want to use IterizerJs:

IterizerJs is not a polyfill, but a library to help you get the most out of ES6 generators. See the GitHub page for details on where you can use it, and how to install it.

More Concise Code

For example, here's the solution for problem 6 in Project Euler:

function sumOfSquares(n) {
    return range(n).map(function(n) {return n * n}).sum();
}

function squaresOfSums(n) {
    return Math.pow(range(n).sum(), 2);
}

console.log(squaresOfSums(10) - sumOfSquares(10));

Better Functional Re-use

To solve problems 3 & 7 from Project Euler in ES5 we might end up creating primes(numPrimes), primes(maxPrime) & nthPrime(n) methods, whereas with IterizerJs we can create a single primes() generator function, and achieve the variations using:

increasing re-use at the functional level.

With IterizerJs

When we later encounter problem 10 from Project Euler ('Find the sum of all the primes below two million'), our intuitions are confirmed when we can solve the problem with this single line of code:

primes().limit(lessThan(2000000)).sum();

With ES6

Alternatively, using only what's available in ES6, you would instead have to write something like this:

function* lessThan(num, items) {
    for(var n of items) {
        if(n < num) {
            yield n;
        }
        else {
            return;
        }
    }
}

Array.from(lessThan(2000000, primes())).sum();

which merely begins to duplicate the functionality provided by IterizerJs anyway.

Globally Installing IterizerJs

Although IterizerJs can be required, parts of it are designed to be installed globally, and the benefits of IterizerJs diminish when this can't be done. There are two flavours of global installation:

Accordingly, two types of installation are typical:

Libraries that are unwilling to install any globals can still use IterizerJs, but will find it of limited value in comparison.

All examples from this point on will assume that the install() method has been called, and that all IterizerJs methods are available globally.

Counted Loops

Thanks to ES6, you will never need to write an arcane C-style for loop again. Instead, you can write code like this:

for(var n of range(10)) {
    // do something with the numbers from 1 to 10
}

Unlike C, Java & JavaScript, etc, which are zero-based, the provided range() method is one-based, since zero based counting normally only makes sense if you are doing pointer arithmetic, or if you are using old-style for loops to index zero-based arrays. Since for...of and for...in allow arrays to be iterated without maintaining an index, and since real-world problems are normally one based, the range() functions start from one unless instructed otherwise.

To iterate the numbers 0 to 9, we could instead write:

for(var n of range(0, 9)) {
    // do something...
}

we can count down from 10 to 1 by inverting the arguments:

for(var n of range(10, 1)) {
    // do something...
}

or we could iterate only even numbers from 2 to 10 by providing a step argument, for example:

for(var n of range(2, 10, 2)) {
    // do something with the numbers 2, 4, 6, 8, 10
}

ES5 Array Methods

IterizerJs provides implementations of the ES5 Array methods, map(), filter(), every(), some() & reduce(), that operate on iterables, and which themselves return an iterable. These can be chained together to produce concise yet descriptive code, such as:

range(-5, 5).filter(isGreaterThan(0)).map(times(10));

Limiting what an iterable object or generator function returns.

Whereas with normal functions, it is often necesarry to create multiple variants of a function depending on what you need it to return, with ES6 generator functions it is often easier to produce functions that return all possible results, and then limit how long they run for externally. To help with this, a limit() method is provided that can be used as follows:

// display the first 5 prime numbers
primes().limit(5);

Or to instead display the 5th to 10th prime numbers we could write:

primes().limit(5, 10);

Alternatively, to display all primes whose value is less than 100, we can write:

primes().limit(isLessThan(100));

To show exactly the 100th prime we can write:

primes().limit(100,100);

or better yet, use the nthItem() convenience method:

primes().nthItem(100);

Similarly, to get the first item we can use the first() method as follows:

primes().first();

Filters

IterizerJs comes with a number of helpful filter functions that can be used with the filter() and limit() methods. These include the numeric filters:

and the string based filters:

All of the filters can be negated by preceding them with not, for example:

programmers().filter(not.equals('Dominic Chambers'));

String Iteration

IterizerJs provides a chars() method for iterating strings which can be used as follows:

// produces the string 'a,b,c'
'abc'.chars().join();

Other helpful methods

A number of other helpful methods like join(), toArray(), sum() & product() are also provided. At any time, the definitive list of available methods can be found by scanning the source code.

Alternatives

Some alternatives to IterizerJs:

If you know of any other alternatives to IterizerJs please let me know so I can link them here.