Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否可以在不超过调用堆栈的情况下展平一个70万条目的数组?_Javascript_Arrays_Callstack - Fatal编程技术网

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

Javascript 是否可以在不超过调用堆栈的情况下展平一个70万条目的数组?,javascript,arrays,callstack,Javascript,Arrays,Callstack,我正在尝试展平一个由100000个项目组成的巨大阵列,我将其展平两次,因为它是二维的,我希望获得第二个阵列中的所有对象: [[{}] 我尝试过使用reduce和concat,如下所示: Concat.firstFlat在一秒钟内处理完毕。secondFlat导致超出最大调用堆栈 let firstArray = Array(100000).fill(Array(7).fill({})); let firstFlat = [].concat.apply([], firstArray); let s

我正在尝试展平一个由100000个项目组成的巨大阵列,我将其展平两次,因为它是二维的,我希望获得第二个阵列中的所有对象:
[[{}]

我尝试过使用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));
我想不出一个解决方案,可能是因为我不太明白调用堆栈到底是什么。我知道它是当前正在执行的所有函数的“堆栈”。但是reduce不应该只有一个函数吗?其中的匿名函数执行一次,然后匿名函数与其他参数一起使用。因此,callstack上应该有一个reduce函数和一个匿名函数。那么它是如何超越调用堆栈的呢?我能想到的唯一原因是reduce是一个函数循环,我不知道如何调用它,但我的意思是:函数a(){a()},它可能就是。在这种情况下,我最好使用forEach/for。但是为什么第一个方法超过了调用堆栈呢?Concat也是一个函数,对吗?我很困惑

我真的非常感谢你的帮助!提前谢谢


编辑:同样的问题似乎也发生在Object.assign上。所有这些函数都依赖于函数循环。我认为应该更新它,这样他们就可以使用async await来代替,这样调用堆栈就不会填满。在这里,我关于reduce是“便利循环函数”的理论是正确的,这一点非常清楚。这将在一秒钟内处理:

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]);
firstArray=Array(100000).fill(Array(7).fill({}));
让列表=[];
for(设i=0;i
祝你的项目好运(如果有人需要这个:)


@MathRobin发布了一个更好的解决方案,请查看:p

建议您使用扩展运算符。更“强大”

第一个展平步骤是使用spread操作符

在“转换”扩展运算符后,它会执行如下操作:

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

这是扁平化的第二级。

+1因为我也想知道调用堆栈上的reduce函数。如果调用堆栈上出现100000次,我也可以使用for循环实现。@Jankapunkt我刚刚测试了它,它似乎只在调用堆栈上出现过一次,reduce和reduce中的匿名函数。这太奇怪了!你能发布准确的错误信息吗?我不敢相信第二个代码段溢出了调用堆栈。我不明白为什么要将其展平两次(甚至在
reduce
代码段中展平三次!)。这是一个数组(对象数组),你需要一个数组(对象数组)。这是一个从2D到1D的扁平化级别。“同样的问题似乎也发生在Object.assign上。所有这些函数都依赖于函数循环。我认为应该对其进行更新,以便它们使用async await来代替,这样调用堆栈就不会填满。”-那没有任何意义。当展平两次时,仍然会超过最大堆栈大小:P我想我现在只使用循环。不明白,你在第一次调用时就得到了70万个项目的展平数组。或者我没有理解你的问题。啊,没关系!我以为你把它压扁过一次,但你曾经。。。ofc。谢谢你的回答@MathRobin你能解释一下
..
应用
有什么不同,以及为什么这会减少堆栈上的参数数量吗?我不知道这背后的理论。很抱歉
Array.prototype.concat(firstArray[0], firstArray[1], ..., firstArray[699999]);