0

Is there a proper way to find the max value of a sparse array with undefined values?

Thanks

var testArr=[undefined,undefined,undefined,3,4,5,6,7];
console.log('max value with undefined is ',(Math.max.apply(null,testArr)));

// max value with undefined is NaN

console.log('max with arr.max()',testArr.max());    

// Error: testArr.max is not a function     

testArr=[null,null,null,3,4,5,6,7];
console.log('max value with null is ',(Math.max.apply(null,testArr)));

// max value with null is 7

I'd prefer not to do forEach if there is a built-in method.

111
  • 1,788
  • 1
  • 23
  • 38
  • forEach is a built-in method – Daniel Weiner Jan 20 '15 at 21:55
  • possible duplicate of [JavaScript: min & max Array values?](http://stackoverflow.com/questions/1669190/javascript-min-max-array-values) – JAL Jan 20 '15 at 21:55
  • @DanielWeiner a built-in method *of finding the max value* – 111 Jan 20 '15 at 22:00
  • `Math.max` attempts to convert its arguments to numbers. Since `undefined` is converted to `NaN` (http://www.ecma-international.org/ecma-262/5.1/#sec-9.3) it will fail with those values. You'll have to iterate over the values. The closest thing to "built-in" is `Array.reduce`. – Daniel Weiner Jan 20 '15 at 22:03
  • Also, `null` is converted to 0 so you'll get the wrong answer if your array is filled with `null`s and negative numbers. – Daniel Weiner Jan 20 '15 at 22:15

2 Answers2

2
testArr.reduce(function(a,b){
  if (isNaN(a) || a === null || a === '') a = -Infinity;
  if (isNaN(b) || b === null || b === '') b = -Infinity;
  return Math.max(a,b)
}, -Infinity);
Daniel Weiner
  • 1,874
  • 12
  • 19
2

None of your examples are true sparse arrays (they don't have any 'holes'), but you could use Array.prototype.filter (ECMA5) to test the value isFinite. For better accuracy ECMA6 will offer Number.isFinite. Remember there are also limits to the number of arguments that Function.prototype.apply can handle (often 65536 arguments). Of course, isFinite may not be suitable for your application, if you want Infinity and -Infinity, then you should use a different test. An empty string with negative numbers would be an issue in this current exampe.

var testArr = [undefined, , , 3, 4, 5, 6, 7];

document.body.textContent = Math.max.apply(null, testArr.filter(function (x) {
    return isFinite(x);
}));
Xotic750
  • 22,914
  • 8
  • 57
  • 79
  • 3
    Simply `testArr.filter(isFinite)` – georg Jan 20 '15 at 23:12
  • @georg Yes indeed, I was thinking that having it verbose may be better for the answer as it is not clear that `isFinite` is the best check for the question raised. – Xotic750 Jan 20 '15 at 23:18