Amar Banerjee
Amar Banerjee

Reputation: 5012

How do I get the second largest element from an array in javascript

I have an integer array like this :

arr[20,120,111,215,54,78];

I need a function taking an array as its argument and returning the second largest element of that array.

Upvotes: 33

Views: 153313

Answers (10)

WapShivam
WapShivam

Reputation: 964

let randomArr = [1,3,5,2,7,6,22,45,67,44];
let sortedArr = randomArr.sort( (a,b) => a-b); // sort array in ASC order
sortedArr.at(-2); // gives 2nd last item in array

Upvotes: 0

Smriti Rastogi
Smriti Rastogi

Reputation: 33

Here is the solution using filter & reduce methods:

arr = [20,120,111,215,54,78];
const secondMax = arr
         .filter((ele)=> ele !== Math.max(...arr))
         .reduce((acc, ele) => ele > acc ? ele : acc , arr[0])

Upvotes: 0

Ja͢ck
Ja͢ck

Reputation: 173522

The most straightforward implementation, without modifying the original array, is to iterate and track the biggest and next biggest:

function nextBiggest(arr) {
  let max = -Infinity, result = -Infinity;

  for (const value of arr) {
    const nr = Number(value)

    if (nr > max) {
      [result, max] = [max, nr] // save previous max
    } else if (nr < max && nr > result) {
      result = nr; // new second biggest
    }
  }

  return result;
}

const arr = ['20','120','111','215','54','78'];
console.log(nextBiggest(arr));

Variations

The behaviour of returning -Infinity if there's no next maximum value distinct from the maximum value in a non-empty array can be modified at the end of the function, depending on the requirements.

Same as maximum

return result == -Infinity ? max : result;

For an empty array, this will return -Infinity as before, but would otherwise return the same value as the maximum if no next distinct maximum is found.

Return null

return result == -Infinity ? null : result;

Same as above, but the return value of null is more indicative of the nonexistence of a next distinct maximum.

Upvotes: 60

ilkinozturk
ilkinozturk

Reputation: 1

function getSecondLargest(nums) {
 return [...new Set(nums)].sort((a,b)=>b-a)[1]    
}

Upvotes: 0

Matyas
Matyas

Reputation: 13702

Original answer

var secondMax = function (){ 
    var arr = [20, 120, 111, 215, 54, 78]; // use int arrays
    var max = Math.max.apply(null, arr); // get the max of the array
    arr.splice(arr.indexOf(max), 1); // remove max from the array
    return Math.max.apply(null, arr); // get the 2nd max
};

demo

Update 1

As pointed out by davin the performance could be enhanced by not doing a splice but temporarily replacing the max value with -Infininty:

var secondMax = function (arr){ 
    var max = Math.max.apply(null, arr), // get the max of the array
        maxi = arr.indexOf(max);
    arr[maxi] = -Infinity; // replace max in the array with -infinity
    var secondMax = Math.max.apply(null, arr); // get the new max 
    arr[maxi] = max;
    return secondMax;
};

Anyway, IMHO the best algorithm is Jack's. 1 pass, with conversion to number. Mine is just short, using builtin methods and only wanted to provide it as an alternative, to show off all the different ways you can achieve the goal.

Update 2

Edge case with multiple values.

As comments pointed it out: this solution "does not work" if we have an array like [3, 3, 5, 5, 5, 4, 4]. On the other hand it would be also a matter of interpretation what we would consider "the 2nd largest element". In the example we have:

  1. 3 elements with the largest value (5) at indices: 2,3,4
  2. 2 elements with the second largest value (4) at indices: 5,6
  3. 2 elements with the second smallest value (3) at indices: 1,2

The 2nd largest element could be interpreted as:

  1. the 2nd (largest element) - 5 at index 3 - assuming that there is an order, and that we aim for a unique value
  2. the (2nd largest) element - 4 at index 5 - assuming that there is an order, and that we aim for a unique value

Upvotes: 50

Mark Walters
Mark Walters

Reputation: 12390

Sort your array from smallest to largest, then grab second one from the end with .length-2

var myArray =['20','120','111','215','54','78'];
var secondLargest = myArray.sort(function(a,b){return a - b})[myArray.length-2];
alert(secondLargest); //120;

Upvotes: 0

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382092

The simplest solution is to sort :

// here's your array :
var stringArray = new Array('20','120','111','215','54','78');

// let's convert it to a real array of numbers, not of strings :
var intArray = stringArray.map(Number);

// now let's sort it and take the second element :
var second = intArray.sort(function(a,b){return b-a})[1]; 

If you don't want the simplest but the fastest (you probably don't need it), then you'd have to write your for loop and store the two greatest elements while looping.

Upvotes: 23

Moumita
Moumita

Reputation: 360

You can try this:

function second_highest(arr)
{
  var second_highest = arr.sort(function(a, b) { return b - a; })[1];
  return second_highest;

}

Upvotes: 0

Kevin Bowersox
Kevin Bowersox

Reputation: 94429

Sort the array and then return the second index.

var arr = ['20','120','111','215','54','78'];

arr.sort(function(a,b){
    return b-a;
});

console.log(arr[1]);

Upvotes: 1

dan-lee
dan-lee

Reputation: 14492

First sort it backwards and then get the second element:

['20','120','111','215','54','78'].sort(function(a, b) { return b - a; })[1];
// '120'

Obviously works with strings too.

Upvotes: 9

Related Questions