У меня есть простой объект JavaScript Array, содержащий несколько чисел.
[267, 306, 108]
Есть ли функция, которая найдет наибольшее число в этом массиве?
У меня есть простой объект JavaScript Array, содержащий несколько чисел.
[267, 306, 108]
Есть ли функция, которая найдет наибольшее число в этом массиве?
Ответы:
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Предупреждение : поскольку на некоторых виртуальных машинах максимальное количество аргументов составляет всего 65535 , используйте цикл for, если вы не уверены, что массив настолько мал.
apply
звонка может очень легко отмыть это.
RangeError: Maximum call stack size exceeded.
Вы можете использовать функцию apply, чтобы вызвать Math.max :
var array = [267, 306, 108];
var largest = Math.max.apply(Math, array); // 306
Как это устроено?
Функция apply используется для вызова другой функции с заданным контекстом и аргументами, представленными в виде массива. Функции min и max могут принимать произвольное количество входных аргументов: Math.max (val1, val2, ..., valN)
Так что если мы позвоним:
Math.min.apply(Math, [1,2,3,4]);
Функция apply выполнит:
Math.min(1,2,3,4);
Обратите внимание, что первый параметр, контекст, не важен для этих функций, так как они являются статическими, они будут работать независимо от того, что передается в качестве контекста.
Самый простой синтаксис с новым оператором распространения :
var arr = [1, 2, 3];
var max = Math.max(...arr);
Источник: Мозилла MDN
Я не эксперт по JS, но я хотел посмотреть, как складываются эти методы, так что это была хорошая практика для меня. Я не знаю, является ли это технически правильным способом тестирования производительности, но я просто запускал их один за другим, как вы можете видеть в моем коде.
Сортировка и получение 0-го значения - безусловно худший метод (и он изменяет порядок вашего массива, что может быть нежелательно). Для остальных разница незначительна, если вы не говорите о миллионах индексов.
Средние результаты пяти прогонов с массивом случайных чисел из 100 000 индексов:
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)
jsperf tests
для вышеупомянутого
Я обнаружил, что для больших массивов (~ 100 тыс. Элементов) на самом деле стоит просто итерировать массив с простым 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;
}
Вы можете отсортировать массив в порядке убывания и получить первый элемент:
[267, 306, 108].sort(function(a,b){return b-a;})[0]
sort(function(a,b){return b-a;})
[...].sort().pop()
Как насчет этого:
var arr = [1,2,3,4];
var largest = arr.reduce(function(x,y){
return (x > y) ? x : y;
});
console.log(largest);
как насчет использования Array.reduce ?
[0,1,2,3,4].reduce(function(previousValue, currentValue){
return Math.max(previousValue,currentValue);
});
-Infinity
.
Почти все ответы используют, 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];
}
Я написал об этом вопросе в своем блоге здесь .
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);
Найти максимальное и минимальное значение простым и ручным способом. Этот код намного быстрее, чем Math.max.apply
; Я пробовал до 1000 тысяч номеров в массиве.
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()
дает неверный результат для пустого массива.
Чтобы найти наибольшее число в массиве, который вам просто нужно использовать Math.max(...arrayName);
, он работает так:
let myArr = [1, 2, 3, 4, 5, 6];
console.log(Math.max(...myArr));
Чтобы узнать больше о Math.max
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
Да, конечно, существуют: Math.max.apply(null,[23,45,67,-45])
и результат возврата 67
;
Простой один лайнер
[].sort().pop()
Вы также можете расширить Array
эту функцию и сделать ее частью каждого массива.
Array.prototype.max = function(){return Math.max.apply( Math, this )};
myArray = [1,2,3];
console.log( myArray.max() );
Вы также можете использовать forEach :
var maximum = Number.MIN_SAFE_INTEGER;
var array = [-3, -2, 217, 9, -8, 46];
array.forEach(function(value){
if(value > maximum) {
maximum = value;
}
});
console.log(maximum); // 217
Использование - 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);
Вы можете попробовать это,
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);
Я только начал с 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
содержит только отрицательные числа.
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;
var tmax = Math.max.apply(Math, max)
, или еще лучше использовать функцию закрытия цикла, например, в stackoverflow.com/a/54980012/7438857 . С этой модификацией лучше ответить на отдельный вопрос, как «найти наибольшее число в многомерном массиве», или на stackoverflow.com/questions/32616910/… . WIP: jsfiddle.net/jamesray/3cLu9for/8 .
Найти максимальное и минимальное значение, используя Bubble Sort
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]);
В соответствии с комментарием @ 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;
}
Рекурсивный подход к тому, как это сделать, используя троичные операторы
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);
Одно 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);
Math.max(...[267, 306, 108]);