简体   繁体   English

递归地展平数组

[英]flatten an array recursively

I tried to implement an array flatten function recursively.我试图递归地实现一个数组展平函数。 Here is the code:这是代码:

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]
*/

But I don't know why the result is not correct.但我不知道为什么结果不正确。 Please help me explain it.请帮我解释一下。

The concat() method returns a new array comprised of the array on which it is called joined with the array(s) and/or value(s) provided as arguments. concat()方法返回一个数组,该数组由调用它的数组与作为参数提供的数组和/或值连接而成。

flatArr.concat(...) doesn't change flatArr ... you need to assign it like so: flatArr.concat(...)不会改变flatArr ... 你需要像这样分配它:

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

Here is a working example with 3 levels deep array:这是一个具有 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>

You can read more about Array.concat function here您可以在此处阅读有关Array.concat 函数的更多信息

You have to assign the returned array after performing the concat ,您必须在执行concat后分配返回的array

 if (arr[i] instanceof Array) {
      flatArr = flatArr.concat(flatten(arr[i]));

concat will not edit the source array. concat不会编辑源数组。 It will give you a new copy.它会给你一个新的副本。 So we have to assign it back to the source array manually.所以我们必须手动将它分配回source array

Maybe you like a real recursive solution:也许你喜欢真正的递归解决方案:

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

This worked for me, hope it helps!这对我有用,希望它有帮助! :) :)

 function flatten(array) { let result = []; array.forEach(el => { if(el instanceof Array){ result.push(...flatten(el)); }else result.push(el) }); return result } console.log(flatten([1, [2, 3, [4]]]));

I am influenced by the Nina Scholtz 's answer ( https://stackoverflow.com/a/35681232/5018572 ) above and made a tail call safe recursive flat array function which avoid using any iteration in it:我受到上面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));

I see that you are trying to write your own function to do this, which is fantastic. 我看到你正在尝试编写自己的函数来做到这一点,这太棒了。 But there is a fantastic framework called lodash which has tons of helper functions like this, case in point flattenDeep : 但是有一个很棒的框架叫做lodash ,它有很多像这样的辅助函数,例如flattenDeep

https://lodash.com/docs#flattenDeep https://lodash.com/docs#flattenDeep

Loop array until all items get flatten, It's a different solution, not exactly what asked in the question.循环数组直到所有项目都变平,这是一个不同的解决方案,不完全是问题中提出的问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM