【问题标题】:how to avoid stack overflow when applying max to a large array in javascript?在javascript中将max应用于大型数组时如何避免堆栈溢出?
【发布时间】:2015-06-12 18:12:05
【问题描述】:

以下代码

var interval = function (a, b) {
          var i, list = [];
          for (i = a; i <= b; i++) {
            list.push(i);
          }
          return list;
        },
    xs = interval(1, 500000);

Math.max.apply(null, xs);

生成一个未捕获的 RangeError:超出最大调用堆栈大小。 如何克服?

请注意,区间函数只是一种快速生成测试数据的方法。

我使用了 Math.max.apply 方法,因为它在此处进行了描述:Mozilla developer network

这不是一个可接受的解决方案,因为 javascript 具有函数调用允许的最大参数数量,感谢 Rocket Hazmat 指出,有关更多信息,请参阅他的答案。

underscore.js 库对 max 函数使用了一个简单的实现,我认为最合适的解决方案是在代码库中包含一个简单的 max 实现并使用它。有关更多详细信息,请参阅@AnotherDev 答案

【问题讨论】:

  • 大声笑 - 通过解决您自己的问题来避免“堆栈溢出”:D
  • 您可以在生成列表时简单地计算最大值,或者通过迭代值。 stackoverflow.com/questions/22747068/…
  • P.S.你不知道最大值吗?您使用 2 个号码拨打 interval。显然,b (500000) 是最大的。
  • @RocketHazmat,间隔没关系,只是演示概念的一种方式,构建假数据

标签: javascript


【解决方案1】:

这里的问题在于这一行:

Math.max.apply(null, xs);

您正在尝试拨打Math.max(1, 2, 3, 4, ..., 500000);。 JavaScript 不喜欢调用具有 500,000 个参数的函数。

有关更多信息,请参阅此答案:https://stackoverflow.com/a/22747272

【讨论】:

  • 感谢@Rocket Hazmat,这似乎是最合适的答案
【解决方案2】:

如果你想变通,你可以使用 underscore.js

source code 看来,它们只是使用 for 循环遍历元素

for (var i = 0, length = obj.length; i < length; i++) {
        value = obj[i];
        if (value > result) {
          result = value;
        }
      }

Here is an example in JSFiddle

var interval = function (a, b) {
          var i, list = [];
          for (i = a; i <= b; i++) {
            list.push(i);
          }
          return list;
        },
    xs = interval(1, 500000);

console.log(_.max(xs))
//prints 500000

【讨论】:

  • 感谢@AnotherDev,我也查看了下划线来源并得出了相同的结论,不允许在大型数组上调用 Math.max.apply,最好的方法是在代码库
猜你喜欢
  • 2010-12-04
  • 2010-11-30
  • 2015-08-10
  • 2020-03-08
  • 2011-09-21
  • 2014-04-13
  • 2011-11-23
  • 2020-02-12
  • 1970-01-01
相关资源
最近更新 更多