1

This function will flatten an Array only two levels deep.

function arrFlattener(arr){
  var newarr = [];
  for(var i = 0; i < arr.length; i++){
    var target = arr[i];
      if(Array.isArray(target)){
        for(var j = 0; j < target.length; j++){
          if(Array.isArray(target[j])){
              for(var k = 0; k < target[j].length; k++){
                newarr.push(target[j][k]);
              }
          } else {
            newarr.push(target[j]);   
          }  
        }
      } else {
         newarr.push(arr[i]);
      }
   }
     return newarr;
}

arrFlattener([1, 2, 3, [4, 5, [6],[7],[8]]]); // returns [1, 2, 3, 4, 5, 6, 7, 8];

Obviously a recursive function is what I need. In pseudo code I imagine a while loop which will run until it can't find a nested array in the current Array.

Any help will be appreciated!

2
  • Think about what it means to be recursive and rework your code. If you get stuck somewhere, SO is here to help. As it stands, SO is not a code writing service. Commented Apr 6, 2017 at 13:50
  • @Cruiser Honestly I think I am stuck here — And it's not like I didn't present any code at all! Commented Apr 6, 2017 at 13:57

3 Answers 3

1

You could call the function right after the check for isArray, then just assign the concatinated result to newarr, because you expect possibly more than one element.

Basically you leave the next iteration to the function call instead of iterating the children array. This eliminates all other following loops (in the old function), because they are done in the function itself with one loop only and a recursive call, if necessary.

function arrFlattener(arr) {
    var newarr = [];
    for (var i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
            newarr = newarr.concat(arrFlattener(arr[i])); // get the result of the recusion
        } else {
            newarr.push(arr[i]);
        }
    }
    return newarr;
}

console.log(arrFlattener([1, 2, 3, [4, 5, [6], [7], [8]]])); // returns [1, 2, 3, 4, 5, 6, 7, 8];

Sign up to request clarification or add additional context in comments.

Comments

1

A simple ES6 solution would be something like

function flatten(arr) {
    const out = [];  // Stores the flattened output; modified by `walk`.
    function walk(arr) {
        arr.forEach((val) => {  // Iterate through `arr`;
            if(Array.isArray(val)) walk(val);  // if the value is an array, call `walk`,
            else out.push(val);  // and otherwise just push the value to `out`.
        });
    }
    walk(arr);
    return out;
}

console.log(flatten([1, 2, 3, [4, 5, [6],[7],[8]]]));

The output is, as required,

[ 1, 2, 3, 4, 5, 6, 7, 8 ]

Comments

1

The following solution is based on a recursively working Array.reduce approach and does acknowledge arguments arrays too ...

var array_flatten = (function (Array, Object) {

  "use strict";

  var
    array_prototype_slice = Array.prototype.slice,
    expose_internal_class = Object.prototype.toString,

    isArguments = function (type) {
      return !!type && (/^\[object\s+Arguments\]$/).test(expose_internal_class.call(type));
    },
    isArray     = ((typeof Array.isArray == "function") && Array.isArray) || function (type) {
      return !!type && (/^\[object\s+Array\]$/).test(expose_internal_class.call(type));
    },

    array_from  = ((typeof Array.from == "function") && Array.from) || function (listAlike) {
      return array_prototype_slice.call(listAlike);
    };

  return function flatten (list) {
    list = (isArguments(list) && array_from(list)) || list;

    if (isArray(list)) {
      list = list.reduce(function (collector, elm) {

        return collector.concat(flatten(elm));

      }, []);
    }
    return list;
  };

}(Array, Object));


console.log(array_flatten([1, 2, 3, [4, 5, [6], [7], [8]]]));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.