Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
4  
Typical solution is Array.prototype.concat.apply([],input) – elclanrs Jan 26 '14 at 10:08
    
@elclanrs this should be an answer. – Sukima Nov 20 '14 at 4:21
    
@elclanrs - This solution fails if there are a large number of arrays in input because it overflows the call stack. Otherwise, you are correct. – Centijo Mar 14 '15 at 15:54
up vote 6 down vote accepted

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)

share|improve this answer
    
Thanks a lot! It seems that a loop is indeed the most efficient approach, as I thought. – Erel Segal-Halevi Jan 26 '14 at 17:04
    
forEach+push is actually doing nothing. – Werlang Feb 23 '15 at 14:49

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.