Tried to determine the second largest number in an array (Javascript) on CodeSandbox. It seems to work fine, but it fails the CodeWars testing. I have added a dummy array just to run my own tests in Sandbox.(Have mercy, I'm a beginner and this is my first StackOverFlow question)
const nums = [3, 100.3, 88, 1, -2.4, 9, 18];
const getSecondLargest = (nums) => {
const descending = nums.sort((a, b) => b - a);
return descending[1];
};
console.log(getSecondLargest(nums)); // console returns 88
EDIT: Okay so I with my super-tired brain I said CodeWars, when I actually meant Hackerrank (so sorry!). I realized they didn't necessarily test with NaNs, but they did have repeating numbers, so using the index of [1] isn't ideal. The exercise is from the 10 Days of Javascript - Day 3: Arrays https://hackerrank.com/domains/tutorials/10-days-of-javascript
So I now tried this code below, and it passes...but my code seems a bit janky, is there a cleaner way to write this, and can I combine it with the isNan logic then?
const nums = [3, 100, 88, 100, -2.4, 9, 18];
const getSecondLargest = (nums) => {
const ascending = nums.sort((a, b) => a - b);
if (ascending[ascending.length - 2] === ascending[ascending.length - 1]) {
return ascending[ascending.length - 3];
} else {
return ascending[ascending.length - 2];
}
};
console.log(getSecondLargest(nums)); // console returns 88
It looks like there maybe strings in the array and you need to handle that. Here are a few ways:
One is to filter the non-numerical stuff out before sorting. You can use isNaN() to test if an object "is not a number".
const getSecondLargest = (nums) => {
const descending = nums
.filter(n => !isNaN(n))
.sort((a, b) => b - a);
return descending.length < 2 ? undefined : descending[1];
};
Another option is to handle the strings in sorting. Push them to the end of the array:
const getSecondLargest = (nums) => {
const descending = nums.sort((a, b) => {
if (isNaN(a) && isNaN(b)) return 0;
if (isNaN(a)) return 1;
if (isNaN(b)) return -1;
return b - a;
});
return descending.length < 2 || isNaN(descending[1]) ? undefined : descending[1];
};
A third way is a simple for loop that keeps track of the 2 highest values:
const getSecondLargest = (nums) => {
let max1 = undefined;
let max2 = undefined;
for (let n of nums) {
if (isNaN(n)) continue;
if (max2 === undefined || n > max2) {
if (max1 === undefined || n > max1 ) {
max2 = max1;
max1 = n;
}
else {
max2 = n;
}
}
}
return max2;
}