JavaScript – Pseudo Array Comprehensions

In my job I have recently switched over to primarily coding in Python and I am loving the change. One thing that I find interesting is list comprehensions. Still, since my first love is JavaScript, I wanted to be able to do something similar in JavaScript and had remembered coming across its likeness in the language (version 1.7). Unfortunately, it doesn’t seem like this is going to be globally supported very soon so below is an alternative:

/**
 * @license Array Builder - By Chris West - MIT License
 * Builds an array either from another array or an object using the values.
 * @param {!Array|!Object} obj  Array or object to be traversed and whose values
 *     will be transformed and possibly added to the returned array.
 * @param {string} varName  The name of the value as it can appear in the
 *     expression and the optFilter.
 * @param {string} expression  The JavaScript expression that will be evaluated
 *     and possibly placed in the array to be returned by this function.
 * @param {string=} optFilter  Optional filter expression that will be evaluated
 *     will be evaluated for each value and only if a truish value results will
 *     the expression be evaluated and the resulting value added to the built
 *     array.
 * @return {!Array}  The array built from the passed array or object.
 */
var buildArray = (function(hasOwnProperty, toString) {
  return function(obj, varName, expression, optFilter) {
    expression = new Function(varName, 'return ' + expression);
    if (optFilter) {
      optFilter = new Function(varName, 'return ' + optFilter);
    }
    
    var ret = [];
    
    function process(key, obj) {
      var value = obj[key];
      if (!optFilter || optFilter.call(obj, value)) {
        ret.push(expression.call(obj, value));
      }
    }
    
    if (toString.call(obj) == '[object Array]') {
      for (var i = 0, len = obj.length; i < len; i++) {
        process(i, obj);
      }
    }
    else {
      for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) {
          process(key, obj);
        }
      }
    }
    
    return ret;
  };
})({}.hasOwnProperty, {}.toString);

As you can see I have already annotated the above function, but here is an example of using it:

buildArray([1,2,3,4,5], 'x', 'x*x');
// Result:  [1, 4, 9, 16, 25]

buildArray({a:'A', b:'B', c:'C'}, 'c', 'c');
// Result:  ['A', 'B', 'C']

buildArray([1,2,3,4,5], 'i', 'String.fromCharCode(64+i)', 'i%2');
// Result:  ['A', 'C', 'E']

Also, if you are wondering why I named this function buildArray it is because this idea of comprehension lists (or JavaScript comprehension arrays) is derived from set-builder notation in mathematics. If you need, feel free to use this function in your code. 8-)

One thought on “JavaScript – Pseudo Array Comprehensions”

Leave a Reply

Your email address will not be published. Required fields are marked *


− 8 = zero

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">