Javascript Javascript递归数组展平
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/30048388/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript recursive array flattening
提问by yxfxmx
I'm exercising and trying to write a recursive array flattening function. The code goes here:
我正在练习并尝试编写一个递归数组展平函数。代码在这里:
function flatten() {
    var flat = [];
    for (var i = 0; i < arguments.length; i++) {
        if (arguments[i] instanceof Array) {
            flat.push(flatten(arguments[i]));
        }
        flat.push(arguments[i]);
    }
    return flat;
}
The problem is that if I pass there an array or nested arrays I get the "maximum call stack size exceeded" error. What am I doing wrong?
问题是,如果我在那里传递一个数组或嵌套数组,我会收到“超出最大调用堆栈大小”错误。我究竟做错了什么?
回答by Arun P Johny
The problem is how you are passing the processing of array, if the value is an array then you are keep calling it causing an infinite loop
问题是你如何传递数组的处理,如果值是一个数组,那么你一直在调用它导致无限循环
function flatten() {
    var flat = [];
    for (var i = 0; i < arguments.length; i++) {
        if (arguments[i] instanceof Array) {
            flat.push.apply(flat, flatten.apply(this, arguments[i]));
        } else {
            flat.push(arguments[i]);
        }
    }
    return flat;
}
Demo: Fiddle
演示:小提琴
Here's a more modern version:
这是一个更现代的版本:
function flatten(items) {
  const flat = [];
  items.forEach(item => {
    if (Array.isArray(item)) {
      flat.push(...flatten(item));
    } else {
      flat.push(item);
    }
  });
  return flat;
}
回答by shyam 74926
[...arr.toString().split(",")]
Use the toString()method of the Object. Use a spread operator (...)to make an array of string and split it by ",".
使用 的toString()方法Object。使用扩展运算符(...)创建一个字符串数组并将其拆分为",".
Example:
例子:
let arr =[["1","2"],[[[3]]]]; // output : ["1", "2", "3"]
回答by franziga
If the item is array, we simply add all the remaining items to this array
如果项目是数组,我们只需将所有剩余的项目添加到该数组中
function flatten(array, result) {
  if (array.length === 0) {
    return result
  }
  var head = array[0]
  var rest = array.slice(1)
  if (Array.isArray(head)) {
    return flatten(head.concat(rest), result)
  }
  result.push(head)
  return flatten(rest, result)
}
console.log(flatten([], []))
console.log(flatten([1], []))
console.log(flatten([1,2,3], []))
console.log(flatten([1,2,[3,4]], []))
console.log(flatten([1,2,[3,[4,5,6]]], []))
console.log(flatten([[1,2,3],[4,5,6]], []))
console.log(flatten([[1,2,3],[[4,5],6,7]], []))
console.log(flatten([[1,2,3],[[4,5],6,[7,8,9]]], []))
回答by Redu
A Haskellesque approach...
一个 Haskelesque 的方法......
function flatArray([x,...xs]){
  return x !== undefined ? [...Array.isArray(x) ? flatArray(x) : [x],...flatArray(xs)]
                         : [];
}
var na = [[1,2],[3,[4,5]],[6,7,[[[8],9]]],10];
    fa = flatArray(na);
console.log(fa);
回答by ulou
If someone looking for flatten array of objects (e.g. tree) so here is a code:
如果有人在寻找扁平对象数组(例如tree),那么这里是一个代码:
function flatten(items) {
  const flat = [];
  items.forEach(item => {
    flat.push(item)
    if (Array.isArray(item.children) && item.children.length > 0) {
      flat.push(...flatten(item.children));
      delete item.children
    }
    delete item.children
  });
  return flat;
}
var test = [
 {children: [
      {children: [], title: '2'}
      ],
  title: '1'},
 {children: [
      {children: [], title: '4'},
      {children: [], title: '5'}
      ],
  title: '3'}
]
console.log(flatten(test))
回答by Tim
If you assume your first argument is an array, you can make this pretty simple.
如果你假设你的第一个参数是一个数组,你可以把它变得非常简单。
function flatten(a) {
    return a.reduce((flat, i) => {
      if (Array.isArray(i)) {
        return flat.concat(flatten(i));
      }
      return flat.concat(i);
    }, []);
  }
If you did want to flatten multiple arrays just concat them before passing.
如果您确实想展平多个数组,只需在传递之前将它们连接起来。
回答by Salman A
Your code is missing an else statement and the recursive call is incorrect (you pass the same array over and over instead of passing its items).
您的代码缺少 else 语句并且递归调用不正确(您一遍又一遍地传递相同的数组而不是传递其项目)。
Your function could be written like this:
你的函数可以这样写:
function flatten() {
    // variable number of arguments, each argument could be:
    // - array
    //   array items are passed to flatten function as arguments and result is appended to flat array
    // - anything else
    //   pushed to the flat array as-is
    var flat = [],
        i;
    for (i = 0; i < arguments.length; i++) {
        if (arguments[i] instanceof Array) {
            flat = flat.concat(flatten.apply(null, arguments[i]));
        } else {
            flat.push(arguments[i]);
        }
    }
    return flat;
}
// flatten([[[[0, 1, 2], [0, 1, 2]], [[0, 1, 2], [0, 1, 2]]], [[[0, 1, 2], [0, 1, 2]], [[0, 1, 2], [0, 1, 2]]]]);
//            [0, 1, 2,   0, 1, 2,     0, 1, 2,   0, 1, 2,       0, 1, 2,   0, 1, 2,     0, 1, 2,   0, 1, 2]
回答by aagamezl
This is a Vanilla JavaScript solution to this problem
这是针对此问题的 Vanilla JavaScript 解决方案
var _items = {'keyOne': 'valueOne', 'keyTwo': 'valueTwo', 'keyThree': ['valueTree', {'keyFour': ['valueFour', 'valueFive']}]};
// another example
// _items = ['valueOne', 'valueTwo', {'keyThree': ['valueTree', {'keyFour': ['valueFour', 'valueFive']}]}];
// another example
/*_items = {"data": [{
    "rating": "0",
    "title": "The Killing Kind",
    "author": "John Connolly",
    "type": "Book",
    "asin": "0340771224",
    "tags": "",
    "review": "i still haven't had time to read this one..."
}, {
    "rating": "0",
    "title": "The Third Secret",
    "author": "Steve Berry",
    "type": "Book",
    "asin": "0340899263",
    "tags": "",
    "review": "need to find time to read this book"
}]};*/
function flatten() {
    var results = [],
        arrayFlatten;
    arrayFlatten = function arrayFlattenClosure(items) {
        var key;
        
        for (key in items) {
            if ('object' === typeof items[key]) {
                arrayFlatten(items[key]);
            } else {
                results.push(items[key]);
            }
        }
    };
    arrayFlatten(_items);
    
    return results;
}
console.log(flatten());
回答by Adara Hv
Modern but not crossbrowser
现代但不是跨浏览器
function flatten(arr) {
  return arr.flatMap(el => {
    if(Array.isArray(el)) {
        return flatten(el);
    } else {
      return el;
    }
  });
}
回答by Gibolt
The clean way to flatten an Array in 2019with ES6is flat():
在2019 年使用ES6扁平化数组的干净方法是flat():
const array = [1, 1, [2, 2], [[3, [4], 3], 2]]
// All layers
array.flat(Infinity) // [1, 1, 2, 2, 3, 4, 3, 2]
// Varying depths
array.flat() // [1, 1, 2, 2, Array(3), 2]
array.flat(2) // [1, 1, 2, 2, 3, Array(1), 3, 2]
array.flat().flat() // [1, 1, 2, 2, 3, Array(1), 3, 2]
array.flat(3) // [1, 1, 2, 2, 3, 4, 3, 2]
array.flat().flat().flat() // [1, 1, 2, 2, 3, 4, 3, 2]
Can I Use- 84% Nov 2019
我可以使用吗- 84% 2019 年 11 月

