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);
[/code]
As you can see I have already annotated the above function, but here is an example of using it:
[code language="javascript"]
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']
[/code]
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. š
1 Comment
JavaScript – Better Array Builder | Chris West's Blog · December 13, 2013 at 12:03 AM
[…] I wrote this post about a way to loosely imitate having array comprehensions in JavaScript. After thinking about it a […]