0

I have the following function:

const biggestNumOfArray = (array) => {
  if (Array.isArray(array)) {
    let biggest = array[0];
    for (i=0; i < array.length; i++) {
      if (array[i] > biggest) {
        biggest = array[i];
      }
    }
    return biggest;
  } else {
    return NaN;
  }
}

It's purpose is to output the biggest number in an array, ignoring non-number values, and return NaN if it isn't an array.

However, consider the following array:

let myArray = [undefined, 8, 74, -22, 269.64, 92];

All of a sudden, it outputs not 269.64, but undefined.

See, if the first element in an array is undefined or NaN, the variable biggest gets stuck on it, as number > NaN and number > undefined on line 5 will always be false, which means the line to change the biggest to the current will never be executed. How do I avoid that?

Note that this doesn't happen with undefineds that aren't first, as number > undefined also outputs false, unallowing to change the biggest to it.

I tried to change the check for the number being the current biggest, by changing it to array[i] > biggest && array[i] != null, using abstract equality to check for it being undefined or null, but it didn't work - I still got back undefined. It also wouldn't cover NaN.

Darryl Noakes
  • 2,207
  • 1
  • 9
  • 27
danik0011
  • 72
  • 10

4 Answers4

2

You could check for finiteness (Number.isFinite) and take only relevant values for checking the biggest value.

const biggestNumOfArray = (array) => {
  let biggest = undefined;
  if (Array.isArray(array)) {
    for (let i = 0; i < array.length; i++) {
      if (!Number.isFinite(array[i])) continue;
      if (biggest === undefined || array[i] > biggest) biggest = array[i];
    }
  }
  return isFinite(biggest) ? biggest : NaN;
};

const myArray = [undefined, 8, 74, -22, 269.64, 92];

console.log(biggestNumOfArray(myArray));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

A simpler method would be to use Array#filter to get rid of non-numeric values, then use spread syntax to pass the rest of the values as separate arguments to Math.max.

const biggestNumOfArray = arr => Array.isArray(arr) ? 
  Math.max(...arr.filter(x => !isNaN(x))) : NaN;

console.log(biggestNumOfArray([undefined, 8, 74, -22, 269.64, 92]));
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
0

//Nullish coalescing operator
const biggestNumOfArray = (array) => {
  if (Array.isArray(array)) {
    let biggest = array[0] ?? 0;
    for (i = 0; i < array.length; i++) {
      if (array[i] > biggest) {
        biggest = array[i];
      }
    }
    return biggest;
  } else {
    return NaN;
  }
}
let myArray = [undefined, 8, 74, -22, 269.64, 92];

console.log(biggestNumOfArray(myArray));
  • Bad assumption that all the numbers in my array are bigger than 0. You can put -Infinity there instead. Thanks for the answer, but i decided to just initially set biggest to -Infinity anyway. – danik0011 Jun 30 '23 at 18:21
0

@GabrielePetrioli suggested to initially set biggest to -Infinity, which worked. Thanks.

I also got took an idea from @nina-scholz to output NaN if biggest isn't a number in the end.

Here is the final fixed and working code:

const biggestNumOfArray = (array) => {
  if(Array.isArray(array)){
    let biggest = -Infinity;
    for(i=0;i<array.length;i++) {
      if(array[i] > biggest) {
          biggest = array[i];
      }
    }
    return typeof(biggest) === 'number' ? biggest : NaN;
  } else { return NaN; }
}
danik0011
  • 72
  • 10