是否可以在不超过调用堆栈的情况下展平一个 700 000 个条目的数组?

Is it possible to flatten an array that is 700 000 entries long without exceeding the call stack?

我正在尝试展平一个包含 100 000 个项目的巨大数组,我将它展平两次,因为它是二维的,我想将所有对象都放在第二个数组中: [ [ {} ] ]

我尝试过使用 reduce 和 concat,像这样:

Concat. firstFlat 在一秒内处理。 secondFlat 导致超出最大调用堆栈。

let firstArray = Array(100000).fill(Array(7).fill({}));
let firstFlat = [].concat.apply([], firstArray);
let secondFlat = [].concat.apply([], firstFlat);

减少。调用堆栈也超出

let array = Array(100000).fill(Array(7).fill({}))
                         .reduce((x, y) => x.concat(y))
                         .reduce((x, y) => x.concat(y))
                         .reduce((x, y) => x.concat(y));

我想不出解决方案,可能是因为我不太了解调用堆栈到底是什么。我知道它是当前正在执行的所有函数的 'stack'。但是 reduce 不应该只有 1 个功能吗?并且里面的匿名函数被执行一次,然后这个匿名函数与其他参数一起使用。所以调用堆栈上应该有 1 个 reduce 函数和 1 个匿名函数。那么它是如何超出调用栈的呢?我能想到的唯一原因是 reduce 是一个函数循环,我不知道如何调用它,但就像我的意思:function a() { a() },它可能是。在那种情况下,我最好使用 forEach/for。但是为什么第一个方法会超出调用堆栈呢? Concat 也只是一个功能,对吗?我很困惑。

非常感谢您的帮助!提前致谢

编辑:Object.assign 似乎也出现了同样的问题。所有这些函数都依赖于函数循环。我认为应该对其进行更新,以便他们改用异步等待,这样调用堆栈就不会填满

OP 在这里,我关于 reduce 是 'convenience loop function' 的理论是正确的,说实话,这很清楚。这是在一秒钟内处理的:

firstArray = Array(100000).fill(Array(7).fill({}));
let list = [];
for(let i = 0; i < firstArray.length; i++)
    for(let j = 0; j < firstArray[i].length; j++) 
        list.push(firstArray[i][j]);

祝你的项目好运(如果有人需要这个:))

@MathRobin 发布了一个更好的解决方案,检查一下:P

建议您使用传播运算符。更多 "powerful".

let firstArray = Array(100000).fill(Array(7).fill({}));
Array.prototype.concat(...firstArray) // (700000) [...]

扁平化的第一步是使用展开运算符。

在展开运算符 "translating" 之后,它执行如下操作:

Array.prototype.concat(firstArray[0], firstArray[1], ..., firstArray[699999]);

这就是第二层的扁平化。