3
var flatten = function (array){
  // TODO: Program me
  var newArray = [];
  for(var i = 0; i<array.length; i++) {
    newArray.push(array[i]);
  }
  return newArray;
}

This are the results excepted:

flatten([1,2,3]) // => [1,2,3]
flatten([[1,2,3],["a","b","c"],[1,2,3]])  // => [1,2,3,"a","b","c",1,2,3]
flatten([[[1,2,3]]]) // => [[1,2,3]]

Test result:

Test Passed

Test Passed

Test Failed: Value is not what was expected
  1. I searched for some heliping function in "Professional JS for Web Developers" but I can't find one for finding the number of dimension of an array.
Sr.Richie
  • 5,680
  • 5
  • 38
  • 62
Bacchus
  • 515
  • 8
  • 22

2 Answers2

9

The trick is that if an element of the input array is an array itself then you should "concat" the element's flattened items into the input array instead of pushing the entire array.

Here is a solution using "reduce" and "Array.isArray(...)" which are only available in newer browsers which support the later specification of ECMAScript 5.1th Edition:

function flatten(array) {
  return array.reduce(function(memo, el) {
    var items = Array.isArray(el) ? flatten(el) : [el];
    return memo.concat(items);
  }, []);
}

flatten([1,2,3])                          // => [1,2,3]
flatten([[1,2,3],["a","b","c"],[1,2,3]])  // => [1,2,3,"a","b","c",1,2,3]
flatten([[[1,2,3]]])                      // => [1, 2, 3]
maerics
  • 151,642
  • 46
  • 269
  • 291
  • You should note that this code will work only in the newest browsers, that support `Array.prototype.reduce` and `Array.isArray`. Otherwise, polyfills must be applied. – VisioN Jun 25 '14 at 16:57
  • @VisioN: indeed, I'm relying heavily on convenient, newer language features =) – maerics Jun 25 '14 at 17:05
  • this answer seams to be outdated: You can use the array.flat() function to flatten an array to any specific depth; Sorce: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat – 0kMike Jun 14 '22 at 08:06
1

Here is one possible solution with using recursion:

function flatten(array, result) {
    result === undefined && (result = []);

    for (var i = 0, len = array.length; i < len; i++) {
        if (Object.prototype.toString.call(array[i]) === '[object Array]') {
            flatten(array[i], result);
        } else {
            result.push(array[i]);
        }
    }

    return result;
}

flatten([1,2,3]);
// [1, 2, 3]

flatten([[1,2,3], ["a","b","c"], [1,2,3]]);
// [1, 2, 3, "a", "b", "c", 1, 2, 3]

flatten([[[1,2,3]]]);
// [1, 2, 3]

DEMO: http://jsfiddle.net/6ZhJ6/

VisioN
  • 143,310
  • 32
  • 282
  • 281
  • 1
    If you look at expected result #3, the intent isn't actually to fully flatten the array but rather just one level. `[[[1,2,3]]]` becomes `[[1,2,3]]` and not `[1,2,3]`. – James Montagne Jun 25 '14 at 16:45
  • @JamesMontagne Not `expected` but `excepted`, which probably means the real results, which the OP received from his code, hence last *"Test Failed"*. – VisioN Jun 25 '14 at 16:47
  • Hah, I read that as expected, though I still assume that was what was intended as the results actually returned by the original code are just a copy of what was passed. The function does basically nothing. – James Montagne Jun 25 '14 at 16:49
  • @JamesMontagne Yeah, I know it's confusing, but I have just proposed another solution (apart from the ones in the related question), which seems to be doing what is *expected* :) – VisioN Jun 25 '14 at 16:51