Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maximum call stack size exceeded with Math.min and Math.max

I have js function to find min and max values in 2d array which works ok on small arrays but when I pass it big array it give me range error:

Maximum call stack size exceeded.

I am using the latest version of Chrome.

function MaxMin2dray(arr, idx){
    return {
       min: Math.min.apply(null, arr.map(function (e) { return e[idx]})),
        max: Math.max.apply(null, arr.map(function (e) { return e[idx]}))
  }
}
like image 745
user889030 Avatar asked Mar 06 '17 10:03

user889030


3 Answers

function minMax2DArray(arr, idx) {
    var max = -Number.MAX_VALUE,
        min = Number.MAX_VALUE;
    arr.forEach(function(e) {
        if (max < e[idx]) {
            max = e[idx];
        }
        if (min > e[idx]) {
           min = e[idx];
       }
    });
    return {max: max, min: min};
}

👆 Edit: Removed use of MIN_VALUE (see post below).

Modernized version

const arrayMinMax = (arr) =>
  arr.reduce(([min, max], val) => [Math.min(min, val), Math.max(max, val)], [
    Number.POSITIVE_INFINITY,
    Number.NEGATIVE_INFINITY,
  ]);
like image 188
bjornl Avatar answered Oct 18 '22 23:10

bjornl


Math.min & Math.max

The Math.min and Math.max most likely crash, or return NaN for big arrays (~10⁷)

(see @DavidWaters & @EugeneGluhotorenko comments).

Instead, you can use old javascript loops like so:

(2nd func is much faster)

function getMax(arr) {
    return arr.reduce((max, v) => max >= v ? max : v, -Infinity);
}

Or

function getMax(arr) {
    let len = arr.length;
    let max = -Infinity;

    while (len--) {
        max = arr[len] > max ? arr[len] : max;
    }
    return max;
}
  • Tested with 1,000,000 items:
    1st function running time (on my machine) was 15.84ms Vs. 2nd function with only 4.32ms.
like image 34
Lior Elrom Avatar answered Oct 18 '22 22:10

Lior Elrom


There is a issue in bjornl's answer. According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE

The MIN_VALUE property is the number closest to 0, not the most negative number, that JavaScript can represent.

The updated code:

function minMax2DArray(arr, idx) {
    var max = -Number.MAX_VALUE,
        min = Number.MAX_VALUE;
    arr.forEach(function(e) {
        if (max < e[idx]) {
            max = e[idx];
        }
        if (min > e[idx]) {
           min = e[idx];
       }
    });
    return {max: max, min: min};
}
like image 21
Roy Yin Avatar answered Oct 18 '22 22:10

Roy Yin