If you want Math.min() to process an array of values, you have to use .apply():
var lowestTime = Math.min.apply(Math, times);
You could also use the new-ish spread syntax:
var lowestTime = Math.min(... times);
but that doesn't work in all environments.
When you pass the array directly, the first thing Math.min() does is try to convert it to a number because that's what it expects: individual numbers. When that happens, through a round-about process the resulting value will be NaN.
The Math.min() function actually expects a series of numbers, but it doesn't know how to handle an actual array, so it is blowing up.
You can resolve this by using the spread operator ...:
var int_array = [1,2];
console.log(Math.min(...int_array)); // returns 1
You could also accomplish this via the Function.apply() function that would essentially do the same thing but isn't as pretty :
var int_array = [1,2];
console.log(Math.min.apply(null,int_array)); // returns 1
You pass an array as first parameter to min function
Math.min([1,2])
From MDN
If at least one of arguments cannot be converted to a number, the result is NaN.
Math.min() requires the arguments to be numbers. It will convert strings to numbers, but each value needs to be in a separate argument -- it won't convert a comma-delimited string to multiple numbers.
Don't use a string for result, use an array. Then you can spread the array into function arguments.
function calculate() {
var array1 = [1, 1, 1];
var array2 = [
[2, 2, 2],
[3, 3, 3],
[4, 4, 4]
];
var i = 0;
var result = [];
for (; i < array2.length; i++) {
result.push(Math.sqrt(Math.pow((array1[0] - array2[i][0]), 2) + Math.pow((array1[1] - array2[i][1]), 2) + Math.pow((array1[2] - array2[i][2]), 2)));
};
console.log(result);
console.log(Math.min(1.7320508075688772, 3.4641016151377544, 5.196152422706632, ));
var minResult = Math.min(...result);
console.log(minResult);
}
<button onclick="calculate()">Click me</button>
You're passing as a param on Math.min a string
"1.7320508075688772,3.4641016151377544,5.196152422706632,"
You can split that string (not recommended)
function calculate() {
var array1 = [1, 1, 1];
var array2 = [
[2, 2, 2],
[3, 3, 3],
[4, 4, 4]
];
var i = 0;
var result = '';
for (; i < array2.length; i++) {
result += Math.sqrt(Math.pow((array1[0] - array2[i][0]), 2) + Math.pow((array1[1] - array2[i][1]), 2) + Math.pow((array1[2] - array2[i][2]), 2)) + ',';
};
console.log(result);
console.log(Math.min(1.7320508075688772, 3.4641016151377544, 5.196152422706632, ));
var minResult = Math.min.apply(null, result.split(",").filter(n => n.trim() !== "").map(Number));
console.log(minResult);
}
<button onclick="calculate()">Click me</button>
Or, add the numbers into an array and find the min value using the function apply as follow
function calculate() {
var array1 = [1, 1, 1];
var array2 = [
[2, 2, 2],
[3, 3, 3],
[4, 4, 4]
];
var i = 0;
var result = [];
for (; i < array2.length; i++) {
result.push(Math.sqrt(Math.pow((array1[0] - array2[i][0]), 2) + Math.pow((array1[1] - array2[i][1]), 2) + Math.pow((array1[2] - array2[i][2]), 2)));
};
console.log(result);
console.log(Math.min(1.7320508075688772, 3.4641016151377544, 5.196152422706632, ));
var minResult = Math.min.apply(null, result);
console.log(minResult);
}
<button onclick="calculate()">Click me</button>
Filter out the NaN entries:
var smallest = Math.min.apply(null, arrayOfNumbers.filter(function(n) { return !isNaN(n); }));
Following zzzzBov’s idea, you could also do this using Array.reduce. This would allow you to skip on intermediary array that would be created from the filter:
var minReduce = function (a, b) { return (isNaN(b) || b > a) ? a : b };
var smallest = arrayOfNumbers.reduce(minReduce, Number.MAX_VALUE);
(I only stored the function separately in a variable to make it more readable in the answer; you are free to use a an anonymous function within the reduce call itself.)
I assume the undefined is actually some variable.
You can substitute -Infinity for any NaN value to ensure a number.
var foo;
Math.max(5, 10, isNaN(foo) ? -Infinity : foo); // returns 10
Same concept can be used on Math.min, but with Infinity:
var foo;
Math.min(5, 10, isNaN(foo) ? Infinity : foo); // returns 5
Write your own max function:
function max() {
var par = []
for (var i = 0; i < arguments.length; i++) {
if (!isNaN(arguments[i])) {
par.push(arguments[i]);
}
}
return Math.max.apply(Math, par);
}
Or shorter using array filtering:
function max() {
var args = Array.prototype.slice.call(arguments);
return Math.max.apply(Math, args.filter(function(val) {
return !isNaN(val);
}));
}
Usage:
max(5, 10, undefined); // output: 10
It seems when you are creating the array, you are creating keys like '01', '02' etc
these are different to index 1 and 2
See the following
const array1 = new Array();
const array2 = new Array();
const array3 = new Array();
array1[0] = 1;
array2['00'] = 2
array3[0] = 3
array3['00'] = 4
console.log(JSON.stringify(array1), typeof array1[0]);
console.log(JSON.stringify(array2), typeof array2[0]);
console.log(JSON.stringify(array3), typeof array3[0]);
see how array2[0] is undefined ... now if you do
const array = new Array();
array['00'] = 10;
array['01'] = 9;
array['02'] = 8;
array['03'] = 7;
array['04'] = 6;
array['05'] = 5;
array['06'] = 4;
array['07'] = 3;
array['08'] = 2;
array['09'] = 1;
array['10'] = 100;
console.log(array);
look at all those undefined before index 10
that's why Math.min results in NaN
Your first filter non-numeric values looks Your contain array non-numeric value.
var filteredArr = arr.filter(function (item) {
return !isNaN(item);
});
For min in the array, you should use
Math.min.apply(Math,array.filter(n => !isNaN(n)))
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);
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])