返回函数具有来自父函数的未定义结果数组

时间:2016-12-27 22:31:05

标签: javascript arrays recursion

我尝试使用ES5创建一个简单的函数来深度展平数组。我在下面的工作,但似乎不是最理想的,因为res结果数组保持在flatten函数之外。



    var arr = [1, 2, [3], [4, [5, [6, 7, 8, 9, 10, 11]]]]
      , res = [];
    function flatten(item){
      if (Array.isArray(item)) {
       item.forEach(el => {
         return flatten(el, res);
       });
      }else {
        res.push(item);
      }
    }
    
    flatten(arr);
    console.log(res); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]




像IIFE这样的东西似乎很接近:

function flatten(item){
  var res = [];
  return (function(ress){
    if (Array.isArray(item)) {
     item.forEach(el => {
       return flatten(el);
     });
    }else {
      res.push(item);
    }
  })(res);
}

但是我没有把它弄得恰到好处,因为res在这里是未定义的。理想情况下,我希望函数的最后一行返回res,以便可以像var f = flatten(arr)一样使用该函数。

NB

*这个问题并没有具体说明如何深度压扁数组,因为有很多答案。我真正感兴趣的是如何在这个实例中将结果变量保存在父函数中 *

3 个答案:

答案 0 :(得分:2)

将递归函数嵌套在main函数中。然后你可以在main函数中包含res变量。



var arr = [1, 2, [3],
  [4, [5, [6, 7, 8, 9, 10, 11]]]
];

function flatten(item) {
  var res = [];

  function flatten_rec(item) {
    if (Array.isArray(item)) {
      item.forEach(el => {
        flatten_rec(el);
      });
    } else {
      res.push(item);
    }
  }
  
  flatten_rec(item);
  return res;
}

var res = flatten(arr);
console.log(res); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]




答案 1 :(得分:0)

以下是使用Array.prototype.reduce的不同方法。



var arr = [1, 2, [3], [4, [5, [6, 7, 8, 9, 10, 11]]]];

var res = arr.reduce( function flatten (a, b) {
  if (Array.isArray(a) && Array.isArray(b)) {
    return b.reduce(flatten, a)
  } else {
    return a.concat(b)
  }
}, [])

console.log(res)

.as-console-wrapper {
  top: 0;
  max-height: 100% !important;
}




答案 2 :(得分:0)

在我看来,迭代方法比递归要好得多。

// Deep copy all arguments into a new, single-level array.
const flatten = (...queue) => {
    const result = [];

    while (queue.length > 0) {
        const item = queue.shift();

        if (Array.isArray(item)) {
            let i = item.length;
            // If the array is non-empty, add its children to the beginning
            // of the queue to keep their order intact.
            while (i--) {
                queue.unshift(item[i]);
            }
        }
        else {
            result.push(item);
        }
    }

    return result;
};