Javascript:使用递归将多维数组就地展平

标签 javascript arrays recursion multidimensional-array flatten

我有以下代码可以展平多维数组

var x = [[[2, 3], 4], 5, [6, 7]];

function flatten(arr) {

  for (var i = 0; i < arr.length; i++) {
    if (arr[i].constructor === Array) {
      subArr = arr[i];
      // Shift the array down based on the space needed for the sub array
      for (var j = arr.length + subArr.length - 2; j > i + subArr.length - 1; j--) {
        arr[j] = arr[j - subArr.length + 1];
      }
      // Insert sub array elements where they belong
      for (var k = 0; k < subArr.length; k++) {
        arr[i + k] = subArr[k]; 
      }
      // Look at arr[i] again in case the first element in the subarray was another array;
      i--;
    }
  }
}

flatten(x);

JSBin 在这里:http://jsbin.com/gazagemabe/edit?js,console

我想使用递归来做到这一点,但我最终陷入困境。我试图在不保留临时数组的情况下做到这一点,但事情似乎变得不正常了。我觉得我缺少递归的一些核心原则。

我意识到我需要一个基本案例。我能想到的唯一情况是当前处于展平状态的数组没有子数组。但是因为我总是通过引用传递数组,所以我没有什么可返回的。

我的伪代码是

function flatten(arr) 

  loop through arr
    if arr[index] is an array
      increase the array length arr[index] length
      flatten(arr[index])
    else
      // unsure what to do here to modify the original array

最佳答案

从内到外进行递归展平。首先对找到的数组调用 flatten 函数,然后将该数组(现在是扁平的)的内容移动到父数组中。通过数组向后循环,这样您就不必为插入的项目调整循环变量。

如您所知,插入的数组是平面的,您可以使用 splice 方法用其项目替换数组。

它的工作原理是这样的:

start with
[[[2, 3], 4], 5, [6, 7]]

flatten [6,7] (which is already flat) and insert:
[[[2, 3], 4], 5, 6, 7]

flatten [[2, 3], 4] recursively calls flatten [2,3] and inserts in that array:
[[2, 3, 4], 5, 6, 7]
then it inserts [2, 3, 4]:
[2, 3, 4, 5, 6, 7]

代码:

function flatten(arr) {
  for (var i = arr.length - 1; i >= 0; i--) {
    if (arr[i].constructor === Array) {
      flatten(arr[i]);
      Array.prototype.splice.apply(arr, [i, 1].concat(arr[i]));
    }
  }
}

var x = [[[2, 3], 4], 5, [6, 7]];

flatten(x);

// Show result in snippet
document.write(JSON.stringify(x));

关于Javascript:使用递归将多维数组就地展平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32491404/

相关文章:

javascript - 如何使用 jquery 隐藏/显示上一个和下一个部分类

python - 如何操作 numpy.loadtxt 后的数据?

java - 使用循环创建二维数组

c - 如何修改我用 C 编写的树遍历程序,使其不依赖于递归?

c# - 从 ASP.MVC 中基于 AOP 的身份验证到 NodeJS

javascript - jQuery 上传文件不适用于 ajax

javascript - 如何在 JavaScript 中将字符串转换为对象数组

c++ - 删除单链表最后一个元素的递归方法?

javascript - React 递归遍历嵌套对象

javascript - 如何在CasperJS中选择带有命名空间的标签?