Javascript 递归展平数组

Javascript 递归展平数组,javascript,recursion,Javascript,Recursion,我尝试递归地实现一个数组展平函数。代码如下: function flatten(arr) { var flatArr = []; for (var i = 0; i < arr.length; i++) { if (arr[i] instanceof Array) { flatArr.concat(flatten(arr[i])); } else { flatArr.push(arr[i]); } } return flatA

我尝试递归地实现一个数组展平函数。代码如下:

function flatten(arr) {
  var flatArr = [];
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] instanceof Array) {
      flatArr.concat(flatten(arr[i]));
    } else {
      flatArr.push(arr[i]);
    }
  }
  return flatArr;
}


console.log(flatten([1, 2, 3, 4, [5]]));
/*
result: [1, 2, 3, 4]
expected: [1, 2, 3, 4, 5]
*/
函数展平(arr){
var flatArr=[];
对于(变量i=0;i

但我不知道为什么结果不正确。请帮我解释一下

执行
concat
后,必须分配返回的
数组

 if (arr[i] instanceof Array) {
      flatArr = flatArr.concat(flatten(arr[i]));
concat
将不会编辑源数组。它会给你一份新的。因此,我们必须手动将其分配回
源数组

concat()
方法返回一个由数组组成的新的数组 在其上调用它与数组和/或值联接 作为论据提供

flatArr.concat(…)
不会改变
flatArr
。。。您需要这样分配它:

flatArr=flatArr.concat('flatten(arr[i]))

下面是一个使用3层深度阵列的工作示例:

函数展平(arr){
var flatArr=[];
对于(变量i=0;i

也许您喜欢真正的递归解决方案:

函数展平(arr){
如果(!arr.length){
返回[];
}
var a=arr.shift();
返回(数组.isArray(a)→展平(a):[a]).concat(展平(arr));
}
document.write(“”+JSON.stringify(flatten([1,2,3,4,5]]))+“”);

document.write(“”+JSON.stringify(扁平化([1,2,3,4,5]],6,7,8]])+“”)循环数组,直到所有项目变平,这是一个不同的解决方案,而不是问题中所要求的

//循环直到所有项目都变平
对于(变量i=0,len=data.length;i
这对我很有效,希望能有所帮助!:)

函数展平(数组){
让结果=[];
array.forEach(el=>{
if(el instanceof数组){
结果:推压(…展平(el));
}其他结果。推送(el)
});
返回结果
}
log(展平([1,2,3,4]])我受上面的答案()的影响,制作了一个尾部调用安全的递归平面数组函数,避免在其中使用任何迭代:

“严格使用”
函数展平(arr,flatArr=[]){
如果(arr.length==0){
返回平面图;
}
var[水头,…剩余量]=arr;
if(数组isArray(头)){
头。推(…休息);
返回扁平化(头部、扁平化);
}否则{
平推(头);
}
返回展平(剩余、展平);
}
var检验=[1,2,3,4,5,6,7][7][3][5]
控制台日志(展平(测试));

问题是您没有将
.concat
返回的数组分配给
flatArr
变量。请参阅我的答案中的一个工作示例。什么是“尾部安全”?还要注意,spread语法总是进行迭代,它只是隐藏在视图中。使用
[head,…rest]=arr执行类似列表的结构递归实际上效率很低(
O(n²)
)。这是一种尾部调用安全,我更正了我丢失的单词。谢天谢地,我从没提过这是最好的解决方案。您只需使用
shift()
获取第一个元素,并使用参数
arr
获取其余代码。这样它的性能会更好。
shift()
也同样低效。它将所有数组元素移动一个位置。我更希望看到基准测试结果,而不是说它效率低下。时间复杂度没有什么需要基准测试的。对于小型阵列,它可能非常快!
// loop until all items are flatten
for (var i = 0, len = data.length; i < len; i++) {
    if (Array.isArray(data[i])) {
        // flatten until there are no more nested
        data = data.concat.apply([], data);
        i--;
        len = data.length;
    }
}