如何使这个数组展平函数在JavaScript中以递归方式运行?

时间:2017-04-06 13:46:22

标签: javascript arrays recursion

此函数将仅将两个级别的数组展平。

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];

显然,我需要一个递归函数。在伪代码中,我想象一个while循环,它将一直运行,直到它无法在当前数组中找到嵌套数组。

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:1)

您可以在检查isArray后立即调用该函数,然后只将结果分配给newarr,因为您可能需要多个元素。

基本上,您将下一次迭代留给函数调用,而不是迭代子数组。这消除了所有其他后续循环(在旧函数中),因为它们是在函数本身中完成的,只有一个循环和一个递归调用,如果需要的话。

&#13;
&#13;
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];
&#13;
&#13;
&#13;

答案 1 :(得分:1)

简单的ES6解决方案就像

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]]]));

根据需要输出

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

答案 2 :(得分:1)

以下解决方案基于递归工作Array.reduce方法,并且也确认arguments数组...

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]]]));