0

So I am building a piece of JavaScript code that returns an array of the largest numbers from each of the provided sub-arrays.

function largestOfFour(arr) {
var array = [];
for (i = 0; i < arr.length; i++) {
// return arr[i].join() on this line gives 4,5,1,3
array.push(Math.max(arr[i].join()));
}
return array;
}

largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

My question is why the: Math.max(arr[i].join()) returns a null value?

If I return arr[i].join() on the previous line (as in code comment) it returns to me 4,5,1,3 for the 1st iteration. If I put in Math.max(4,5,1,3) it returns 5which is what I want.

Assigning the arr[i].join() to a variable and then putting in Math.max also returns null. I would run theMath.maxthrough a reduce function, but it won't let me run a function through a loop.

I'm sure there is a simple reason why this doesn't work, but I can't find an explanation anywhere. I don't need help with a solution to the overall problem - just help with understanding why the Math.max won't work.

Nompumelelo
  • 929
  • 3
  • 17
  • 28
Simon
  • 11
  • 1
  • 2

5 Answers5

6

Math.max(4,5,1,3) and Math.max('4,5,1,3') are two very different operations. Passing a string that contains comma separated values is not the same as passing multiple arguments:

function foo(x, y, z) {
   console.log('x', x);
   console.log('y', y);
   console.log('z', z);
}

foo(1,2,3);
foo('1,2,3');
foo([1,2,3].join());

Math.max expects to be passed multiple numbers, not a single string.


The question you should be asking is:

How can I pass the elements of an array as arguments to a function?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
2

You want to use the array with math max, problem is max wants a list of arguments. So we use apply to do it

var arr = [1,4,5,9]
var max = Math.max.apply( Math, arr );
console.log(max);

And using map with it, you can get all the largest numbers

var nums = [[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]

var result = nums.map(arr =>  Math.max.apply(Math, arr))
//var result = nums.map(function(arr){ return Math.max.apply(Math, arr)})
console.log(result)
epascarello
  • 204,599
  • 20
  • 195
  • 236
1

As wrote in the document,and mentioned in comments:

The join() method joins all elements of an array (or an array-like object) into a string.

Therefore, remove join and rewrite max like the following:

function largestOfFour(arr) {
    var array = [];
    for (i = 0; i < arr.length; i++) {
        array.push(Math.max(...arr[i]));
    }
    return array;
}

console.log(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));
OmG
  • 18,337
  • 10
  • 57
  • 90
  • Thanks, I originally tried this solution, but my console wasn't running the necessary ES6. – Simon Jun 26 '17 at 12:15
0

function largest(arr) {
  var array = [];

  for (var i = 0; i < arr.length; i++) {
    array.push(Math.max.apply(null, arr[i]));
  }

  return array;
}

var array = [
  [4, 5, 1, 3],
  [13, 27, 18, 26],
  [32, 35, 37, 39],
  [1000, 1001, 857, 1]
];

var result = largest(array);
console.log(result);
0

From the MDN docs on the return value of Math.max

The largest of the given numbers. If at least one of the arguments cannot be converted to a number, NaN is returned.

If you actually observe the array variable in your function, you'll see [NaN, NaN, NaN, NaN] at the end of the loop. That is a indication that at least one of the arguments cannot be converted to a number. And if you just check one of the inputs to the Math.max function, you'll see what's going wrong

// Random array
var a = [1, 2, 3, 4];

// The join
console.log(a.join()); // "1,2,3,4"

// Try to convert the join to a Number
console.log(Number(a.join())); // NaN

// Try getting a max out of the join. Your case here
console.log(Math.max(a.join())); // NaN
maazadeeb
  • 5,922
  • 2
  • 27
  • 40