Найти 2-е по величине значение в массиве, содержащем дубликаты наибольшего целого числа

#javascript #arrays #while-loop

#javascript #массивы #цикл while

Вопрос:

Я пытаюсь найти второе по величине число в массиве чисел, но наибольшее число появляется дважды, поэтому я не могу просто удалить его из массива и выбрать новое наибольшее число.

array = [0, 3, 2, 5, 5] (следовательно, 3 это 2-е по величине значение)

У меня есть этот код, где я могу явно вернуть 3, но это не сработало бы в других массивах:

     function getSecondLargest(nums) {

      var sorted_array = nums.sort(function (a,b) {return a - b;});
      var unique_sorted_array = sorted_array.filter(function(elem, index, self) {
    return index === self.indexOf(elem);
})

    return unique_sorted_array[unique_sorted_array.length - 2];
}

return unique_sorted_array[unique_sorted_array.length - 2];
  

Если бы я хотел сделать его более динамичным, есть ли способ, которым я мог бы определить наибольшее значение массива, а затем сравнить его с каждой итерацией массива?

Я думал, что что-то вроде:

 var greatestNum = sortedArray[-1]

while(greatestNum != i) do {
  //check for the first number that doesn't equal greatestNum
}
  

Будем признательны за любую помощь.

Комментарии:

1. Нужно ли обрабатывать случай, когда все элементы массива равны? Или когда длина массива меньше 2?

2. В этом нет необходимости, но это может быть полезно для тех, кто будет искать это в будущем.

Ответ №1:

Вы можете просто сначала создать Set, а затем отсортировать по убыванию и взять 1-й элемент индекса

 let array = [0, 3, 2, 5, 5]

let op = [...new Set(array)].sort((a,b) => b-a)[1]

console.log(op)  

Для тех, кто думает с точки зрения эффективности. это лучший способ, IMO

 let array = [0, 3, 2, 5, 5]

let max = -Infinity
let secondMax = -Infinity

for(let i=0; i<array.length; i  ){
  if(array[i] > max){
    secondMax = max
    max = array[i]
  }
}

console.log(secondMax)  

Комментарии:

1. Также можно сделать .sort().reverse() , если ваш ленивый

2. @GetOffMyLawn да, но это делает одно и то же дважды, когда вы можете сделать за один раз

3. @Code Maniac 1 для второго. Это было ново для меня

4. Спасибо @CodeManiac — действительно краткий ответ, и я ценю, что вы добавили свое решение в «Выполнить фрагмент кода»

Ответ №2:

Я бы рекомендовал сделать что-то более похожее

 const nums = [0, 3, 2, 5, 5];
nums.sort(function (a,b) {return b - a;})

for (let i = 1; i < nums.length; i  ) {
  if (nums[0] !== nums[i]) {
    return nums[i];
  }
}
  

что должно быть намного эффективнее (особенно с точки зрения памяти), чем преобразование в set и обратно…

Комментарии:

1. Кстати, когда вы говорите о скорости и производительности, вам следует делать это даже без сортировки. в этом случае можно использовать только две переменные и простой цикл for

Ответ №3:

Попробуйте это:

 var intArray = stringArray.map(nums); // now let's sort and  take the second element :

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

};
  

Ответ №4:

Для тех, кто хочет сделать это с помощью Math.max(). Вот самый простой способ сделать это.

 const getSecondLargest = function (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([3, 5, 9, 9, 9])); //5
  

Примечание: Math.max() не принимает массив, поэтому мы должны использовать Math.max.apply() для передачи массива в функцию. -Бесконечность меньше любого отрицательного конечного числа.