是否可以在不超过调用堆栈的情况下展平一个 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]);
这就是第二层的扁平化。
我正在尝试展平一个包含 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]);
这就是第二层的扁平化。