JackNova
JackNova

Reputation: 3931

how to avoid stack overflow when applying max to a large array in javascript?

The following code

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);

generates an Uncaught RangeError: Maximum call stack size exceeded. How to overcome?

Note that the interval function is just a quick way to generate test data.

I used the Math.max.apply method because it is described here: Mozilla developer network

This is not an acceptable solution because javascript has a maximum number of arguments allowed for a function call, thanks to Rocket Hazmat for pointing it out, see his answer for more informations.

The underscore.js library uses a simple implementation for the max function, and I believe that the most appropriate solution is to include a simple max implementation in the codebase and use it. See @AnotherDev answer for more details

Upvotes: 0

Views: 1193

Answers (2)

tcigrand
tcigrand

Reputation: 2397

If you want a work around, you can use underscore.js

From the source code, it looks like they just loop through the elements using a for loop

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

Upvotes: 3

gen_Eric
gen_Eric

Reputation: 227270

The issue here is with the line:

Math.max.apply(null, xs);

You are trying to call Math.max(1, 2, 3, 4, ..., 500000);. JavaScript doesn't like calling a function with 500,000 parameters.

See this answer for more info: https://stackoverflow.com/a/22747272

Upvotes: 4

Related Questions