Problem
Problem: Concat all sub-arrays of a given array.
Example input: [[0, 1], [2, 3], [4, 5]]
Example output: [0, 1, 2, 3, 4, 5]
Solution A: Use a loop
var flattened=[];
for (var i=0; i<input.length; ++i) {
var current = input[i];
for (var j=0; j<current.length; ++j)
flattened.push(current[j]);
}
Solution B: Use reduce
var flattened = input.reduce(function(a, b) {
return a.concat(b);
}, []);
Solution B looks much shorter and easier to understand, but, it seems to be much more resource-wasteful – for each element of the input, a new array is created – the concatenation of a and b. On the contrary, solution A uses a single array ‘flattened’, which is updated during the loop.
So, my question is: which solution is better? Is there a solution that combines the best of both worlds?
Solution
Here is the performance test for these two and couple more approaches (one suggested by @elclanrs in the comments).
The performance differences will vary significantly across different browsers, and even different version on same browser, as browser these days try to optimize javascript very aggressively.
Unless you are dealing with very large arrays or this operation is performed repeatedly in quick succession, I would suggest you to use simplest and clearest approach. But, that being said the loop solution is also not that complex or big anyway (and it performs better than others especially on firefox)
Taking @elclanrs solution in the comments above and modifying slightly to overcome the limitations with ultra long arrays and argument expansion, you could use something like this:
function flattenLongArray(input) {
var LIMIT = 32768;
var end, result = [];
for(var i = 0; i < input.length; i+=LIMIT) {
end = Math.min(i+LIMIT, input.length) - 1;
Array.prototype.concat.apply(result, input.slice(i, end));
}
return result;
}
This is admittedly verbose, but it works.