递归地展平数组

时间:2016-02-28 09:46:11

标签: 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 flatArr;
}


console.log(flatten([1, 2, 3, 4, [5]]));
/*
result: [1, 2, 3, 4]
expected: [1, 2, 3, 4, 5]
*/

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

7 个答案:

答案 0 :(得分:6)

  

concat()方法返回由数组组成的 new 数组   调用它与数组和/或值连接   作为论据提供。

flatArr.concat(...)不会更改flatArr ...您需要像这样分配:

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

这是一个包含3级深度数组的工作示例:

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

var arr = [1,2,3,4,[5,6,[7,8]]];
var flatten = flatten(arr);

$('#result').html(JSON.stringify(flatten));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>

您可以在此处详细了解Array.concat function

答案 1 :(得分:4)

您必须在执行array

后分配返回的concat
 if (arr[i] instanceof Array) {
      flatArr = flatArr.concat(flatten(arr[i]));

concat不会编辑源数组。它会给你一个新的副本。因此,我们必须手动将其分配回source array

答案 2 :(得分:2)

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

function flatten(arr) {
    if (!arr.length) {
        return [];
    }
    var a = arr.shift();
    return (Array.isArray(a) ? flatten(a) : [a]).concat(flatten(arr));
}

document.write('<pre>' + JSON.stringify(flatten([1, 2, 3, 4, [5]])) + '</pre>');
document.write('<pre>' + JSON.stringify(flatten([1, [2, 3, [4, 5]], 6, 7, [8]])) + '</pre>');

答案 3 :(得分:2)

这对我有用,希望对您有所帮助! :)

openssl ciphers -V

答案 4 :(得分:1)

我受到上面 Nina Scholtz 的回答 (https://stackoverflow.com/a/35681232/5018572) 的影响,并做了一个尾调用安全递归平面数组函数,避免在其中使用任何迭代:

'use strict'

function flatten(arr, flatArr = []) {
  if (arr.length === 0) {
    return flatArr;
  }

  var [head, ...rest] = arr;

  if (Array.isArray(head)) {
    head.push(...rest);
    
    return flatten(head, flatArr);
  } else {
    flatArr.push(head);
  }

  return flatten(rest, flatArr);
}

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

答案 5 :(得分:0)

我看到你正在尝试编写自己的函数来执行此操作,这太棒了。但是有一个名为lodash的奇妙框架,其中包含大量辅助函数,例如flattenDeep

https://lodash.com/docs#flattenDeep

答案 6 :(得分:0)

循环数组,直到所有项目变平,这是一个不同的解决方案,而不是问题中的问题。

// 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;
    }
}