81

I am trying to get the highest number from a simple array:

data = [4, 2, 6, 1, 3, 7, 5, 3];

alert(Math.max(data));

I have read that if even one of the values in the array can't be converted to number, it will return NaN, but in my case, I have double-checked with typeof to make sure they are all numbers, so what can be my problem?

Sinister Beard
  • 3,570
  • 12
  • 59
  • 95
Matt Welander
  • 8,234
  • 24
  • 88
  • 138
  • 6
    just see [doc, about Math.max](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) :-) _If at least one of arguments cannot be converted to a number, the result is **NaN**._ – Grundy Sep 18 '15 at 08:19
  • That's not a valid dupe in my opinion. This question is not how to do it, but more why does it not work with an array. The dupe question does not seem to answer this – musefan Sep 18 '15 at 08:26
  • @musefan, see link to doc above: this array just cannot be converted to a number :-) – Grundy Sep 18 '15 at 08:27
  • Oh, I didn't see the difference between passing an array of numbers to Math.max() instead of a comma-separated list of numbers... so in my original code, I was trying to get the max of [array] and [nothing else]. – Matt Welander Sep 18 '15 at 08:27
  • @Grundy: Yeah I know the reason, I was just about to answer myself explaining the problem before it was closed. But my point stands, that dupe is not the same question, nor does it answer this question. It provides a solution sure, but it doesn't answer why it doesn't work with array of numbers – musefan Sep 18 '15 at 08:28
  • @MattWelander, so see answer in dup question – Grundy Sep 18 '15 at 08:28
  • @musefan You cannot call `max` on array, so as you can see in the answers of the http://stackoverflow.com/questions/1669190/javascript-min-max-array-values question, you're passing the `Math` as context and calling `max` function from `Math` and passing the array elements as individual parameters to `max()` – Tushar Sep 18 '15 at 08:34
  • @musefan, but answer _why it doesn't work with array of numbers_ stay in docs – Grundy Sep 18 '15 at 08:35
  • @Grundy: Yeah, so the answer to this question might be to reference that particular part of the docs. We don't close question because there is a document somewhere on the internet that answers it already – musefan Sep 18 '15 at 08:38
  • 1
    @musefan, so possibly you right :-) add vote to reopen – Grundy Sep 18 '15 at 08:39
  • @Tushar: Stop talking to me, you're obviously not cut out for this conversation. You appear to be under the impression I don't know the reason, and completely missing my point that the question is not a dupe. Show me an answer in that dupe that says why it doesn't work with arrays – musefan Sep 18 '15 at 08:39
  • 1
    @musefan in one [answer](http://stackoverflow.com/a/6102340/2881286) from dupe link http://aaroncrane.co.uk/2008/11/javascript_max_api/ so, it a bit explain why :-) – Grundy Sep 18 '15 at 08:41
  • 1
    @Grundy: But links don't count. They are for supporting answers, not providing them. That link could break at anytime, especially as it looks like its a personal site – musefan Sep 18 '15 at 08:43

5 Answers5

120

The reason why your code doesn't work is because Math.max is expecting each parameter to be a valid number. This is indicated in the documentation as follows:

If at least one of arguments cannot be converted to a number, the result is NaN.

In your instance you are only providing 1 argument, and that 1 value is an array not a number (it doesn't go as far as checking what is in an array, it just stops at knowing it isn't a valid number).

One possible solution is to explicitly call the function by passing an array of arguments. Like so:

Math.max.apply(Math, data);

What this effectively does is the same as if you manually specified each argument without an array:

Math.max(4, 2, 6, 1, 3, 7, 5, 3);

And as you can see, each argument is now a valid number, so it will work as expected.

Spreading an array

You can also spread the array. This essentially treats the array as if each item is being passed as it's own argument.

Math.max(...data);
musefan
  • 47,875
  • 21
  • 135
  • 185
42

if you see doc for Math.max you can see next description

Because max() is a static method of Math, you always use it as Math.max(), rather than as a method of a Math object you created (Math is not a constructor).

If no arguments are given, the result is -Infinity.

If at least one of arguments cannot be converted to a number, the result is NaN.

When you call Math.max with array parameter like

Math.max([1,2,3])

you call this function with one parameter - [1,2,3] and javascript try convert it to number and get ("1,2,3" -> NaN) fail.
So result as expected - NaN

NOTE: if array with just one number - all work correctly

 Math.max([23]) // return 23

because [23] -> "23" -> 23 and covert to Number is done.


If you want get max element from array you should use apply function, like

Math.max.apply(Math,[1,2,3])

or you can use the new spread operator

Math.max(...[1,2,3])
Community
  • 1
  • 1
Grundy
  • 13,356
  • 3
  • 35
  • 55
29

It's not working because you are passing an array as the parameter instead of comma separated numbers. Try spreading the array like this:

data = [4, 2, 6, 1, 3, 7, 5, 3];    
alert(Math.max(...data));
Bijoy Thangaraj
  • 5,434
  • 4
  • 43
  • 70
1

If you have to use the Math.max function and one number of the array might be undefined, you could use:

x = Math.max(undefined || 0, 5)
console.log(x) // prints 5
dpolicastro
  • 1,379
  • 1
  • 14
  • 22
0

You will need to use the spread operator while passing array as an argument to the Math.max() method.

alert(Math.max(...data)); //this should resolve it.