Як я можу знайти найбільшу кількість, що міститься в масиві JavaScript?


206

У мене є простий об’єкт JavaScript Array, що містить кілька номерів.

[267, 306, 108]

Чи є функція, яка знайшла б найбільше число в цьому масиві?


22
Math.max(...[267, 306, 108]);
Джексонкр

Відповіді:


315

Відмовтеся на допомогу:

Array.max = function( array ){
    return Math.max.apply( Math, array );
};

Попередження : оскільки на деяких VM максимальна кількість аргументів становить лише 65535 , використовуйте цикл for, якщо ви не впевнені, що масив такий малий.


15
Ах, але тепер на ньому наклеєний SO Наклейка якості лише злегка криво!
Shog9

2
FWIW, якщо продуктивність є фактором вашого рішення, я би спробував це порівняти з вашою власною легко кодованою функцією, щоб переконатися, що вона працює добре. Ми схильні вважати, що нативна реалізація буде швидшою; насправді вартість applyдзвінка може вимити це дуже легко.
TJ Crowder

2
Що робити, якщо довжина мого масиву перевищує межу кількості параметрів?
lukas.pukenis

3
@CrescentFresh відповідно до цього: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… це жорстко кодується 65535. Відповідно до цього: code.google.com/p/v8/isissue/detail?id = 172 і, знаючи, що аргументи висуваються на стек, ми знаємо, що це не необмежено
lukas.pukenis

9
Також цей метод не є надійним. Це не вдається, якщо ваш масив більший, ніж максимальний розмір стека, що призводить доRangeError: Maximum call stack size exceeded.
Марк Лундін,

197

Ви можете скористатися функцією застосування для виклику Math.max :

var array = [267, 306, 108];
var largest = Math.max.apply(Math, array); // 306

Як це працює?

застосовувати використовується для виклику іншої функції із заданим контекстом та аргументами, наданими у вигляді масиву. Функції min та max можуть приймати довільну кількість вхідних аргументів: Math.max (val1, val2, ..., valN)

Тож якщо ми зателефонуємо:

Math.min.apply(Math, [1,2,3,4]);

Функція застосувати буде виконувати:

Math.min(1,2,3,4);

Зауважте, що перший параметр, контекст, не важливий для цих функцій, оскільки вони статичні, вони працюватимуть незалежно від того, що передано як контекст.


2
На кого ви поставили свої відповіді з великим зусиллям: D
ShrekOverflow

1
Це чудово. Але що робити, якщо довжина мого масиву перевищує обмеження розміру параметра (функції)? Що тоді ?
lukas.pukenis

1
Мені подобається ця відповідь краще за інших, тому що вона пояснює, що все робить і чому. +1
Марвін

59

Найпростіший синтаксис із новим оператором розповсюдження :

var arr = [1, 2, 3];
var max = Math.max(...arr);

Джерело: Mozilla MDN


2
Однак і розповсюдження (...), і застосунок будуть або відмовити, або повернути неправильний результат, якщо в масиві буде занадто багато елементів developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Зелений

@Green FWIW, обмеження кількості параметрів - 65536 (принаймні в Chrome) ([джерело ( bugs.webkit.org/show_bug.cgi?id=80797)] ). Тож якщо у вашому масиві більше 65536 елементів, ця відповідь не буде працювати.
mgthomas99

4
65536 нікому повинно вистачити
vsync

41

Я не експерт з JS, але хотів побачити, як складаються ці методи, тому це було для мене гарною практикою. Я не знаю, чи це технічно правильний спосіб перевірити працездатність, але я просто запустив їх один за одним, як ви бачите в моєму коді.

Сортування та отримання 0-го значення - це найгірший метод (і він змінює порядок вашого масиву, що може не бути бажаним). Для інших різниця незначна, якщо ви не говорите про мільйони індексів.

Середні результати п’яти пробіжок зі 100 000-індексним масивом випадкових чисел:

  • скоротити взяли 4.0392ms бігти
  • Math.max.apply прийняв 3.3742ms бігти
  • сортування та отримання 0-го значення займало 67,4724 мс для запуску
  • Math.max у межах (() зайняв 6,5804 мс для запуску
  • призначений для користувача findmax функція сприймала 1.6102ms для запуску

var performance = window.performance

function findmax(array)
{
  var max = 0,
      a = array.length,
      counter

  for (counter=0;counter<a;counter++)
  {
      if (array[counter] > max)
      {
          max = array[counter]
      }
  }
  return max
}

function findBiggestNumber(num) {
  var counts = []
  var i
  for (i = 0; i < num; i++) {
    counts.push(Math.random())
  }

  var a, b

  a = performance.now()
  var biggest = counts.reduce(function(highest, count){
        return highest > count ? highest : count
      }, 0)
  b = performance.now()
  console.log('reduce took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest2 = Math.max.apply(Math, counts)
  b = performance.now()
  console.log('Math.max.apply took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest3 = counts.sort(function(a,b){return b-a;})[0]
  b = performance.now()
  console.log('sorting and getting the 0th value took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest4 = counts.reduce(function(highest, count){
        return Math.max(highest,count)
      }, 0)
  b = performance.now()
  console.log('Math.max within reduce() took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest5 = findmax(counts)
  b = performance.now()
  console.log('custom findmax function took ' + (b - a) + ' ms to run')
  console.log(biggest + '-' + biggest2 + '-' + biggest3 + '-' + biggest4 + '-' + biggest5)

}

findBiggestNumber(1E5)

7
Для мене це найкраща відповідь на це питання.
rzelek

1
Я зробив jsperf testsдля вищезазначеного
vsync

37

Я виявив, що для великих масивів (~ 100k елементів) насправді варто просто повторити масив із скромним forциклом, виконуючи ~ 30% краще, ніж Math.max.apply():

function mymax(a)
{
    var m = -Infinity, i = 0, n = a.length;

    for (; i != n; ++i) {
        if (a[i] > m) {
            m = a[i];
        }
    }

    return m;
}

Результати порівняння


3
FWIW, виходить 84% зараз на Chrome 31.
Ілан Білала

31

Ви можете сортувати масив у порядку зменшення та отримати перший елемент:

[267, 306, 108].sort(function(a,b){return b-a;})[0]

4
Я б припустив, що ви також можете просто сортувати та отримати останній предмет ...?
Shog9

@ Shog9: Так, але вам потрібно буде самостійно вказати функцію порівняння:sort(function(a,b){return b-a;})
Gumbo

9
Ага. Я думав більше, як:[...].sort().pop()
Shog9

4
"знаходження числа приймає порядок n, сортування займає між порядком (n журналом n) на замовлення (n у квадраті), залежно від використовуваного алгоритму сортування" - webmasterworld.com/forum91/382.htm
Marco Luglio

2
Також пам’ятайте, що це сортує масив, який може бути або не бути бажаним побічним ефектом. Розчин, що застосовується, є більш ефективним і не має побічних ефектів.
Калеб

28

Як щодо цього:

var arr = [1,2,3,4];

var largest = arr.reduce(function(x,y){
       return (x > y) ? x : y;
});

console.log(largest);

Якби я вперше побачив цю відповідь (зараз у нижній частині списку), я би врятував дві години.
користувач139301

1
Підхід Math.max, мабуть, самий стандартний, але я отримував переповнення стека, коли масив був занадто великим (500 КК). Ця відповідь є швидкою та ефективною, і я в кінцевому підсумку використовував себе, тому я підтримую цю пропозицію.
Джей

8

як щодо використання Array.reduce ?

[0,1,2,3,4].reduce(function(previousValue, currentValue){
  return Math.max(previousValue,currentValue);
});

Початкове значення слід встановити на -Infinity.
Ja͢ck

@Jack, навіщо це потрібно? навіть з масивом всіх від’ємних чисел я отримую дійсний результат.
CodeToad

1
Це крайній випадок, коли масив порожній.
Ja͢ck

5

Практично у всіх відповідях використовується Math.max.apply()приємно та безтурботно, але має обмеження.

Аргументи функції розміщуються на стеку, який має зворотний бік - ліміт. Тож якщо ваш масив більший за ліміт, він не вдастьсяRangeError: Maximum call stack size exceeded.

Щоб знайти розмір стека викликів, я використав цей код:

var ar = [];
for (var i = 1; i < 100*99999; i++) {
  ar.push(1);
  try {
    var max = Math.max.apply(Math, ar);
  } catch(e) {
    console.log('Limit reached: '+i+' error is: '+e);
    break;
  }
}

Він виявився найбільшим на FireFox на моїй машині - 591519 . Це означає, що якщо масив містить більше 591519 елементів, Math.max.apply()це призведе до RangeError .

Найкращим рішенням цієї проблеми є ітераційний спосіб (кредит: https://developer.mozilla.org/ ):

max = -Infinity, min = +Infinity;

for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max)
    max = numbers[i];
  if (numbers[i] < min)
    min = numbers[i];
}

Я писав про це питання у своєму блозі тут .


1
Це не справедливо. Я хочу, щоб відповідь тут, на SO, не було іншого посилання на інший сторонній ресурс. Особливо, коли це поєднується з "тут все погано, але йди, дивись, це так чудово в моєму блозі ..."
osa

@SergeyOrshanskiy посилання на третю сторону працює дуже добре, якщо вона оновлюється новими відзнаками та рішеннями. Також не потрібно почуватися ображеним. Люди просто хочуть вирішити і ваші проблеми. Я теж хотів це вирішити, тому писав про це у своєму блозі
lukas.pukenis

5

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

const inputArray = [ 1, 3, 4, 9, 16, 2, 20, 18];
const maxNumber = Math.max(...inputArray);
console.log(maxNumber);


2
Однак і розповсюдження (...), і застосунок будуть або відмовити, або повернути неправильний результат, якщо в масиві буде занадто багато елементів developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Зелений

5

Простий та ручний спосіб пошуку максимальної та мінімальної цінності. Цей код набагато швидше, ніж Math.max.apply; Я спробував до 1000k чисел у масиві.

function findmax(array)
{
    var max = 0;
    var a = array.length;
    for (counter=0;counter<a;counter++)
    {
        if (array[counter] > max)
        {
            max = array[counter];
        }
    }
    return max;
}

function findmin(array)
{
    var min = array[0];
    var a = array.length;
    for (counter=0;counter<a;counter++)
    {
        if (array[counter] < min)
        {
            min = array[counter];
        }
    }
    return min;
}

findmax()дає неправильний результат, якщо в масиві є лише від’ємні числа; findmin()дає неправильний результат для порожнього масиву.
Ja͢ck


3

Так, звичайно, є: Math.max.apply(null,[23,45,67,-45]) і результат повернення 67;



1

Не забувайте про те , що упаковка може бути зроблена з Function.prototype.bind, що дає вам «все-рідну» функцію .

var aMax = Math.max.apply.bind(Math.max, Math);
aMax([1, 2, 3, 4, 5]); // 5

1

Ви також можете розширити, Arrayщоб мати цю функцію і зробити її частиною кожного масиву.

Array.prototype.max = function(){return Math.max.apply( Math, this )};
myArray = [1,2,3];

console.log( myArray.max() );

1
Страшенно неефективна.
Френк Шмітт

@FrankSchmitt, дякую, я згоден. Оригінальна відповідь не була вдалим рішенням. Сортування за замовчуванням не сортує числа, воно розглядає елементи як рядки. Відредагував мою відповідь, щоб мати правильний сорт.
Іц

Це не було моєю суттю. Сортування масиву для пошуку максимуму само по собі є надзвичайно неефективним, оскільки воно займає щонайменше N операцій N log N, тоді як знайти максимум можна за N операцій.
Френк Шмітт


1

Використання - Array.prototype.reduce()це круто!

[267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val)

де acc = акумулятор і val = значення струму ;

var a = [267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val);

console.log(a);


1

Ви можете спробувати це,

var arr = [267,306,108];
var largestNum = 0;
for(i=0;i<arr.length;i++) {
   if(arr[i]>largest){
    var largest = arr[i];
   }
}
console.log(largest);

1

Я щойно почав із JS, але думаю, що цей метод був би гарним:

var array = [34, 23, 57, 983, 198];<br>
var score = 0;

for(var i = 0; i = array.length; i++) {
  if(array[ i ] > score) {
    score = array[i];
  }
}

У цьому виникнуть проблеми, якщо вони arrayмістять лише від’ємні числа.
Teepeemm

0

Знайдіть найбільшу кількість у багатовимірному масиві

var max = []; 

for(var i=0; arr.length>i; i++ ){

   var arra = arr[i];
   var largest = Math.max.apply(Math, arra);
   max.push(largest);

   }
return max;

Завжди доцільно додати до вашого коду детальне пояснення, особливо якщо вже є безліч інших відповідей. Чому це один інший / кращий?
Bowdzone

@Bowdzone, дякую за коментар. цей спосіб є дуже базовим, що спрощує розуміння з невеликим знанням лише кількох методів.
Liveindream

Це не повертає найбільше число, воно повертає масив найбільшої кількості кожного масиву в багатовимірному масиві. Вам потрібно буде додати, наприклад var tmax = Math.max.apply(Math, max), або ще краще, використовувати функцію закриття циклу, наприклад, в stackoverflow.com/a/54980012/7438857 . З цією модифікацією краще відповісти на окреме запитання, як ви "знайдете найбільшу кількість у багатовимірному масиві", або на stackoverflow.com/questions/32616910/… . WIP: jsfiddle.net/jamesray/3cLu9for/8 .
Джеймс Рей

stackoverflow.com/a/32617019/7438857 є кращою відповіддю на правильне запитання, хоча ця відповідь не відповідає на вищезазначене питання, вона повертає найбільшу кількість у кожному масиві в багатовимірному масиві.
Джеймс Рей

0

Виконати це:

Array.prototype.max = function(){
    return Math.max.apply( Math, this );
};

А тепер спробуйте [3,10,2].max()повернути10


0

Знайдіть значення Максимальне та мінімальне значення за допомогою сортування бульбашок

    var arr = [267, 306, 108];

    for(i=0, k=0; i<arr.length; i++) {
      for(j=0; j<i; j++) {
        if(arr[i]>arr[j]) {
          k = arr[i];
          arr[i] = arr[j];
          arr[j] = k;
        }
      }
    }
    console.log('largest Number: '+ arr[0]);
    console.log('Smallest Number: '+ arr[arr.length-1]);


1
(1) Масиви Javascript вже мають функцію сортування O (n log n). (2) Сорт бульбашки - O (n ^ 2). (3) Знаходження min і max дорівнює O (n).
Teepeemm

0

Спробуйте це

function largestNum(arr) {
  var currentLongest = arr[0]

  for (var i=0; i< arr.length; i++){
    if (arr[i] > currentLongest){
      currentLongest = arr[i]
    }
  }

  return currentLongest
}

1
Чи істотно відрізняється ця відповідь від багатьох інших на цій сторінці?
Teepeemm

0

Відповідно до коментаря @ Quasimondo , який, здається, був значною мірою пропущений, нижче, здається, найкращі показники, як показано тут: https://jsperf.com/finding-maximum-element-in-an-array . Зауважте, що, хоча для масиву у запитанні, продуктивність може не мати суттєвого ефекту, для великих масивів продуктивність стає важливішою, і, як зазначається, використання Math.max(), навіть не працює, якщо довжина масиву перевищує 65535. Дивіться також цю відповідь .

function largestNum(arr) {
    var d = data;
    var m = d[d.length - 1];
    for (var i = d.length - 1; --i > -1;) {
      if (d[i] > m) m = d[i];
    }
    return m;
}

0

Рекурсивний підхід щодо того, як це зробити за допомогою потрійних операторів

const findMax = (arr, max, i) => arr.length === i ? max :
  findMax(arr, arr[i] > max ? arr[i] : max, ++i)

const arr = [5, 34, 2, 1, 6, 7, 9, 3];
const max = findMax(arr, arr[0], 0)
console.log(max);


0

for/ofРішення одного циклу:

const numbers = [2, 4, 6, 8, 80, 56, 10];


const findMax = (...numbers) => {
  let currentMax = numbers[0]; // 2

  for (const number of numbers) {
    if (number > currentMax) {
      console.log(number, currentMax);
      currentMax = number;
    }
  }
  console.log('Largest ', currentMax);
  return currentMax;
};

findMax(...numbers);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.