Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

JEP Collections

Gozala edited this page May 24, 2012 · 4 revisions

In SDK we face several different collection types that we need to iterate, filter, map and reduce. There is well established convention for doing this operations on JS arrays that can be employed to use consistent API across other types we deal with.

Scope

  • Many XPCOM APIs return instances of nsISimpleEnumerator
  • Some code uses Mozilla specific, non standard iterators & generators
  • JS [Array]'s
  • JS objects used as hash maps.
  • Some APIs represent collections of items as objects that can be iterated via for but object[key] is not a value mapped to a key.

Solution

There several possible solutions to address this:

Mimic arrays

One solution would be wrap all non Array types values into an object providing implementations of Array methods by preserving semantics of the wrappee (iterators should stay lazy, enumerators should open on consumption):

var result = enumerable(enumerator).
  filter(predicate).
  map(f).
  reduce(accumulate);

var result = pairs(object).
  filter(predicate).
  map(f).
  reduce(accumulate);

This solution has some inherent constraints:

  • No way to interrupt iteration.
  • We will need wrapper per type.
  • Use of methods is insecure as they may be tempered.

underscore like API

Underscore is one of the most popular JS libraries and most used library on the server side JS. This is may be a good opportunity to employ popular API to solve our problem:

let { map, filter, reduce, chain } = require('sdk/collection')

var result = reduce(map(filter(enumerator, predicate), f), accumulate);
// Or use `chain`

var value = chain(enumerator).
  filter(predicate).
  map(f).
  reduce(accumulate);

Note that these let's us solve some of the inherent problems with a first option. For example underscore provides function find that lets one stop an iteration on first match. Also we could implement take or similar to generalize it further. Also we could use Array.prototype methods on arrays to guard against tempered ones.

More read