0

I am trying to find the second largest value in an array but my code returns the second smallest value in an array. Any pointers as to where i'm missing it? The code is suppose to simply loop backwards through the array, matching any value that is less than the highest value and also "one less than" the highest value.

function getSecondLargest(nums) {
  let sNums = nums.sort();
  let max = sNums.length - 1;
  for (let i = sNums.length; i > 0; i--) {
    if (sNums[i] < max && (sNums[i] === (max - 1))) {
      return sNums[i];
    }
  }
 }
 
 console.log(getSecondLargest([8,7,9,4,5,6,3,2.10,22,42,101]))
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Tino
  • 3
  • 2
  • 3
    If you're going to sort the array, then might as well sort it properly in descending order then just get the second element - this will be the second largest number. E.g. `let sNums = nums.sort((a, b) => b - a);` then return `sNums[1]` – Jayce444 May 04 '21 at 06:03
  • I made you a working snippet. Please do the same in the future – mplungjan May 04 '21 at 06:05
  • The error is also `let max = sNums.length - 1;` which is an index and not a value - you might want to consider `Number.MAX_SAFE_INTEGER` unless you just opt for the super simple method in the comment above – mplungjan May 04 '21 at 06:06
  • @Jayce444 This does not solve the problem if the input contains more than one largest number for instance [0, 2, 3, 10, 10] – Francisco de Castro May 04 '21 at 06:08
  • @FranciscodeCastro Then he can make a set – mplungjan May 04 '21 at 06:11
  • ALso https://www.google.com/search?q=javascript+sort+second+largest&oq=javascript+sort+second+largest – mplungjan May 04 '21 at 06:12
  • He is asking help to figure out what is wrong with his algorithm and not a solution for this. Given his algorithm which is almost correct what is going wrong and why? – Francisco de Castro May 04 '21 at 06:13
  • @FranciscodeCastro The first error is to start max off with an index and not an actual number – mplungjan May 04 '21 at 06:23
  • @Tino, please check my answer. – Ayaz May 04 '21 at 06:24
  • 1
    @mplungjan https://stackoverflow.com/questions/19740047/why-do-javascript-sort-a-numeric-array-not-in-numeric-order is relevant since they will probably face it *later* but not the issue OP is facing *now* since they don't have a two digits number in their list. – Kaiido May 04 '21 at 06:39
  • @Kaiido *I* added the array to op's question – mplungjan May 04 '21 at 07:14

3 Answers3

2

You can sort it by descending and take the second item.

function getSecondLargest(nums) {
  return nums.sort((n1,n2) => n2-n1)[1];
}
    
console.log(getSecondLargest([10,20,40,30,80,90]));

If there are duplicates, you can use this.

function getSecondLargest(nums) {
  return nums.sort((n1,n2) => n2-n1).filter(function(item, pos, ary)    {
        return !pos || item != ary[pos - 1];
   })[1];
}
    
console.log(getSecondLargest([10,20,40,30,80,90,90]));

The issue with Tino's code is finding the second max number. It should be let max = sNums[sNums.length - 1]; instead of let max = sNums.length - 1;, the loop should start at sNums.length - 1and it goes until i >= 0, and the if statement just needs to compare the current value with the max value. If a second largest is not found return null. Null means all the elements in the array have the same value.

function getSecondLargest(nums) {
  let sNums = nums.sort((a,b) => a-b);
  let max = sNums[sNums.length - 1];
  for (let i = sNums.length - 1; i >= 0; i--) {
    if (sNums[i] < max) {
      return sNums[i];
    }
  }
  return null;
 }
 
 console.log(getSecondLargest([8,7,9,9,4,5,6,3,2]))
Ayaz
  • 2,111
  • 4
  • 13
  • 16
  • 1
    This does not solve the problem if the input contains more than one largest number for instance [0, 2, 3, 10, 10] – Francisco de Castro May 04 '21 at 06:08
  • 1
    Your algorithm work but as I said in may comment @Tino is asking for help with his algorithm and not a different algorithm to solve his problem. His algorithm is in the right path but with some errors that can be explained. – Francisco de Castro May 04 '21 at 06:17
  • @Francisco, Updated my answer to find and fix the Tino's code. – Ayaz May 04 '21 at 06:23
  • 2
    @Ayaz, yes, but keep the right sorting: let sNums = nums.sort((a,b) => a-b); otherwise, with 2-digit numbers it will not work. – sinisake May 04 '21 at 06:27
0

Ok, my suggestion - ES6 to the rescue

See other answers and comment why original code did not work

const getSecondLargest = numArr => Array.from(new Set(numArr)) // makes array of unique entries
  .sort((a,b) => b-a)[1]; // sorts in descending numerical order
 
console.log(getSecondLargest([8,7,9,4,5,6,3,2.10,22,42,101]))
mplungjan
  • 169,008
  • 28
  • 173
  • 236
0

If you want to avoid sort method. Here's the simplest solution IMO. It'll also work if there's duplicate numbers of largest integer.

function getSecondLargest(arr) {
  const largest = Math.max.apply(null, arr);
  for (let i = 0; i < arr.length; i++) {
    if (largest === arr[i]) {
      arr[i] = -Infinity;
    }
  }
  return Math.max.apply(null, arr);
}
console.log(getSecondLargest([2, 3, 4, 4, 4])); //3