Найти минимальный / максимальный элемент массива в JavaScript
Как я могу легко получить минимальный или максимальный элемент массива JavaScript?
Пример Psuedocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
61 ответ
Как насчет расширения встроенного объекта Array для использования Math.max
/ Math.min
вместо:
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
Array.prototype.min = function() {
return Math.min.apply(null, this);
};
Вот JSFiddle.
Расширение встроенных модулей может вызвать конфликты с другими библиотеками (некоторые видят), так что вам может быть удобнее просто apply
"ИНГ Math.xxx()
к вашему массиву напрямую:
var min = Math.min.apply(null, arr),
max = Math.max.apply(null, arr);
В качестве альтернативы, если ваш браузер поддерживает ECMAScript 6, вы можете использовать оператор распространения, который работает аналогично apply
метод:
var min = Math.min( ...arr ),
max = Math.max( ...arr );
var max_of_array = Math.max.apply(Math, array);
Для полного обсуждения см.: http://aaroncrane.co.uk/2008/11/javascript_max_api/
Использование оператора распространения (ES6)
Math.max(...array); // the same with "min" => Math.min(...array);
const array = [10, 2, 33, 4, 5];
console.log(
Math.max(...array)
)
Для больших массивов (~10⁷ элементов), Math.min
а также Math.max
оба выдают следующую ошибку в Node.js.
RangeError: превышен максимальный размер стека вызовов
Более надежное решение - не добавлять каждый элемент в стек вызовов, а вместо этого передавать массив:
function arrayMin(arr) {
return arr.reduce(function (p, v) {
return ( p < v ? p : v );
});
}
function arrayMax(arr) {
return arr.reduce(function (p, v) {
return ( p > v ? p : v );
});
}
Если вас беспокоит скорость, следующий код будет примерно в 3 раза быстрее Math.max.apply
на моем компьютере. Смотрите http://jsperf.com/min-and-max-in-array/2.
function arrayMin(arr) {
var len = arr.length, min = Infinity;
while (len--) {
if (arr[len] < min) {
min = arr[len];
}
}
return min;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (arr[len] > max) {
max = arr[len];
}
}
return max;
};
Если ваши массивы содержат строки вместо цифр, вам также необходимо преобразовать их в числа. Приведенный ниже код делает это, но он замедляет код ~ 10 раз на моей машине. Смотрите http://jsperf.com/min-and-max-in-array/3.
function arrayMin(arr) {
var len = arr.length, min = Infinity;
while (len--) {
if (Number(arr[len]) < min) {
min = Number(arr[len]);
}
}
return min;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (Number(arr[len]) > max) {
max = Number(arr[len]);
}
}
return max;
};
ТЛ; др
var max = Math.max(...arrayOfNumbers);
официальный Math.max()
Документация MDN
Следующая функция использует Function.prototype.apply(), чтобы найти максимальный элемент в числовом массиве.
getMaxOfArray([1, 2, 3])
эквивалентноMath.max(1, 2, 3)
, но вы можете использоватьgetMaxOfArray()
на программно построенных массивах любого размера.function getMaxOfArray(numArray) { return Math.max.apply(null, numArray); }
Или с новым оператором распространения, получить максимум массива становится намного проще.
var arr = [1, 2, 3]; var max = Math.max(...arr);
Если вы параноик, как я об использовании Math.max.apply
(что может привести к ошибкам при использовании больших массивов в соответствии с MDN), попробуйте это:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.max(a, b);
});
}
function arrayMin(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
});
}
Или в ES6:
function arrayMax(array) {
return array.reduce((a, b) => Math.max(a, b));
}
function arrayMin(array) {
return array.reduce((a, b) => Math.min(a, b));
}
К сожалению, необходимы анонимные функции (вместо использования Math.max.bind(Math)
так как reduce
не просто пройти a
а также b
к своей функции, но и i
и ссылка на сам массив, поэтому мы должны убедиться, что мы не пытаемся вызвать max
на тех, кто тоже.
Math.min & Math.max
Math.min
а также Math.max
обе являются рекурсивными операциями, которые, скорее всего, требуют больших массивов (больше чем ~10⁷ элементов).
Вместо этого вы можете использовать старые циклы JavaScript следующим образом:
function getMinMax(arr) {
return arr.reduce(({min, max}, v) => ({
min: min < v ? min : v,
max: max > v ? max : v,
}), { min: arr[0], max: arr[0] });
}
Или (лучше во время выполнения):
function getMinMax(arr) {
let min = arr[0];
let max = arr[0];
let i = arr.length;
while (i--) {
min = arr[i] < min ? arr[i] : min;
max = arr[i] > max ? arr[i] : max;
}
return { min, max };
}
* Протестировано с 1 000 000 предметов:
Для справки: время выполнения 1-й функции (на моей машине) составило 15,84 мс против 2-й функции с 4,32 мс.
Два способа короче и проще:
let arr = [2, 6, 1, 0]
// Way 1:
let max = Math.max.apply(null, arr)
//Way 2:
let max = arr.reduce(function(a, b) {
return Math.max(a, b);
});
.apply
часто используется, когда целью является вызов переменной функции со списком значений аргументов, например
Math.max([value1[,value2, ...]])
Функция возвращает наибольшее из нуля или более чисел.
Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20
Math.max()
Метод не позволяет передавать в массив. Если у вас есть список значений, из которых вам нужно получить наибольшее, вы обычно вызываете эту функцию с помощью Function.prototype.apply (), например
Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20
Однако,начиная с ECMAScript 6, вы можете использовать оператор распространения:
Оператор распространения позволяет развернуть выражение в местах, где ожидаются несколько аргументов (для вызовов функций) или несколько элементов (для литералов массива).
Используя оператор распространения, вышеприведенное можно переписать так:
Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20
При вызове функции с помощью оператора переменной можно даже добавить дополнительные значения, например
Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50
Бонус:
Оператор Spread позволяет вам использовать синтаксис литерала массива для создания новых массивов в ситуациях, когда в ES5 вам нужно будет вернуться к императивному коду, используя комбинацию push
, splice
, так далее.
let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']
Вы делаете это путем расширения типа Array:
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
Усиленный отсюда (Джон Резиг)
Простое решение, чтобы найти минимальное значение за Array
элементов использовать Array
функция-прототип reduce
:
A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9
или используя встроенную в JavaScript функцию Math.Min() (спасибо @Tenflex):
A.reduce((min,val) => Math.min(min,val), A[0]);
Это устанавливает min
в A[0]
, а затем проверяет A[1]...A[n]
строго ли он меньше текущего min
, Если A[i] < min
затем min
обновляется до A[i]
вернув это значение.
Для краткого современного решения можно выполнить reduce
операция над массивом, отслеживая текущие минимальное и максимальное значения, поэтому массив повторяется только один раз (что является оптимальным).
let array = [100, 0, 50];
let [min, max] = array.reduce(([prevMin,prevMax], curr)=>
[Math.min(prevMin, curr), Math.max(prevMax, curr)], [Infinity, -Infinity]);
console.log("Min:", min);
console.log("Max:", max);
Еще один способ сделать это:
var arrayMax = Function.prototype.apply.bind(Math.max, null);
Использование:
var max = arrayMax([2, 5, 1]);
Другие уже дали некоторые решения, в которых они дополняют Array.prototype
, Все, что я хочу в этом ответе, чтобы уточнить, должно ли это быть Math.min.apply( Math, array )
или же Math.min.apply( null, array )
, Так какой контекст следует использовать, Math
или же null
?
При прохождении null
как контекст для apply
тогда контекст по умолчанию будет глобальным объектом (window
объект в случае браузеров). Проходя Math
объект в качестве контекста будет правильным решением, но это не повредит передаче null
или. Вот пример, когда null
может вызвать проблемы, при украшении Math.max
функция:
// decorate Math.max
(function (oldMax) {
Math.max = function () {
this.foo(); // call Math.foo, or at least that's what we want
return oldMax.apply(this, arguments);
};
})(Math.max);
Math.foo = function () {
print("foo");
};
Array.prototype.max = function() {
return Math.max.apply(null, this); // <-- passing null as the context
};
var max = [1, 2, 3].max();
print(max);
Выше будет выбрасывать исключение, потому что this.foo
будет оцениваться как window.foo
, который undefined
, Если мы заменим null
с Math
все будет работать как положено, и на экране будет выведена строка "foo" (я проверял это с помощью Mozilla Rhino).
Вы можете в значительной степени предположить, что никто не украшал Math.max
так что, проходя null
будет работать без проблем.
Я удивлен, что никто не упомянул функцию сокращения.
var arr = [1, 10, 5, 11, 2]
var b = arr.reduce(function(previous,current){
return previous > current ? previous:current
});
b => 11
arr => [1, 10, 5, 11, 2]
Это может соответствовать вашим целям.
Array.prototype.min = function(comparer) {
if (this.length === 0) return null;
if (this.length === 1) return this[0];
comparer = (comparer || Math.min);
var v = this[0];
for (var i = 1; i < this.length; i++) {
v = comparer(this[i], v);
}
return v;
}
Array.prototype.max = function(comparer) {
if (this.length === 0) return null;
if (this.length === 1) return this[0];
comparer = (comparer || Math.max);
var v = this[0];
for (var i = 1; i < this.length; i++) {
v = comparer(this[i], v);
}
return v;
}
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
function getMaxOfArray(numArray) {
return Math.max.apply(null, numArray);
}
var arr = [100, 0, 50];
console.log(getMaxOfArray(arr))
это сработало для меня.
Я думал, что поделюсь своим простым и понятным решением.
Для мин:
var arr = [3, 4, 12, 1, 0, 5];
var min = arr[0];
for (var k = 1; k < arr.length; k++) {
if (arr[k] < min) {
min = arr[k];
}
}
console.log("Min is: " + min);
И для макс:
var arr = [3, 4, 12, 1, 0, 5];
var max = arr[0];
for (var k = 1; k < arr.length; k++) {
if (arr[k] > max) {
max = arr[k];
}
}
console.log("Max is: " + max);
Let array = [267, 306, 108] let longest = Math.max(... массив);
Для больших массивов (~10⁷ элементов), Math.min
а также Math.max
вызывает RangeError (превышен максимальный размер стека вызовов) в файле node.js.
Для больших массивов быстрое и грязное решение:
Array.prototype.min = function() {
var r = this[0];
this.forEach(function(v,i,a){if (v<r) r=v;});
return r;
};
array.sort((a, b) => b - a)[0];
Дает максимальное значение в массиве чисел.
array.sort((a, b) => a - b)[0];
Дает минимальное значение в массиве чисел.
let array = [0,20,45,85,41,5,7,85,90,111];
let maximum = array.sort((a, b) => b - a)[0];
let minimum = array.sort((a, b) => a - b)[0];
console.log(minimum, maximum)
Помимо использования математических функций max и min, еще одна функция, которую можно использовать, - это встроенная функция sort(): вот и мы
const nums = [12, 67, 58, 30].sort((x, y) =>
x - y)
let max = nums[0]
let min = nums[nums.length -1]
Для массива, содержащего объекты вместо чисел:
arr = [
{ name: 'a', value: 5 },
{ name: 'b', value: 3 },
{ name: 'c', value: 4 }
]
Вы можете использовать reduce
чтобы получить элемент с наименьшим значением (min)
arr.reduce((a, b) => a.value < b.value ? a : b)
// { name: 'b', value: 3 }
или наибольшее значение (макс.)
arr.reduce((a, b) => a.value > b.value ? a : b)
// { name: 'a', value: 5 }
Вы можете использовать следующую функцию в любом месте вашего проекта:
function getMin(array){
return Math.min.apply(Math,array);
}
function getMax(array){
return Math.max.apply(Math,array);
}
И тогда вы можете вызвать функции, передающие массив:
var myArray = [1,2,3,4,5,6,7];
var maximo = getMax(myArray); //return the highest number
пусть arr=[20,8,29,76,7,21,9]
Math.max.apply(Math, arr); // 76
Итерируйте, отслеживая, как вы идете.
var min = null;
var max = null;
for (var i = 0, len = arr.length; i < len; ++i)
{
var elem = arr[i];
if (min === null || min > elem) min = elem;
if (max === null || max < elem) max = elem;
}
alert( "min = " + min + ", max = " + max );
Это оставит мин / макс пустым, если в массиве нет элементов. Устанавливает min и max за один проход, если в массиве есть какие-либо элементы.
Вы также можете расширить массив с помощью range
метод, использующий выше, чтобы позволить повторное использование и улучшить читаемость. Смотрите рабочую скрипку на http://jsfiddle.net/9C9fU/
Array.prototype.range = function() {
var min = null,
max = null,
i, len;
for (i = 0, len = this.length; i < len; ++i)
{
var elem = this[i];
if (min === null || min > elem) min = elem;
if (max === null || max < elem) max = elem;
}
return { min: min, max: max }
};
Используется в качестве
var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];
var range = arr.range();
console.log(range.min);
console.log(range.max);
У меня работает следующий код:
var valueList = [10,4,17,9,3];
var maxValue = valueList.reduce(function(a, b) { return Math.max(a, b); });
var minValue = valueList.reduce(function(a, b) { return Math.min(a, b); });
У меня была та же проблема, мне нужно было получить минимальное и максимальное значения массива и, к моему удивлению, не было встроенных функций для массивов. Прочитав много, я решил самостоятельно протестировать "топ-3" решения:
- дискретное решение: цикл FOR для проверки каждого элемента массива относительно текущего значения max и / или min;
- Решение APPLY: отправка массива во внутренние функции Math.max и / или Math.min с использованием apply(null,array);
- Решение REDUCE: повторная проверка каждого элемента массива с использованием метода limit (function).
Тестовый код был таким:
function GetMaxDISCRETE(A)
{ var MaxX=A[0];
for (var X=0;X<A.length;X++)
if (MaxX<A[X])
MaxX=A[X];
return MaxX;
}
function GetMaxAPPLY(A)
{ return Math.max.apply(null,A);
}
function GetMaxREDUCE(A)
{ return A.reduce(function(p,c)
{ return p>c?p:c;
});
}
Массив A был заполнен 100 000 случайных целых чисел, каждая функция была выполнена 10 000 раз на Mozilla Firefox 28.0 на настольном компьютере Intel Pentium 4 2.99 ГГц с Windows Vista. Время указывается в секундах, получаемых функцией performance.now(). Результаты были такими, с 3 дробными цифрами и стандартным отклонением:
- Дискретное решение: среднее значение =0,161 с, сд =0,078
- Применить решение: среднее =3,571 с, SD =0,487
- УМЕНЬШИТЬ решение: среднее =0,350 с, SD =0,044
Раствор REDUCE был на 117% медленнее, чем дискретный раствор. Решение APPLY оказалось хуже, на 2118% медленнее, чем дискретное решение. Кроме того, как заметил Питер, он не работает для больших массивов (около 1 000 000 элементов).
Кроме того, чтобы завершить тесты, я протестировал этот расширенный дискретный код:
var MaxX=A[0],MinX=A[0];
for (var X=0;X<A.length;X++)
{ if (MaxX<A[X])
MaxX=A[X];
if (MinX>A[X])
MinX=A[X];
}
Время: среднее =0,218 с, сд =0,094
Таким образом, он на 35% медленнее, чем простое дискретное решение, но одновременно извлекает как максимальные, так и минимальные значения (для их извлечения любому другому решению потребуется как минимум вдвое больше). Как только ОП потребуются оба значения, дискретное решение будет лучшим выбором (даже если две отдельные функции, одна для расчета максимума, а другая для вычисления минимума, они превзойдут второе лучшее, решение REDUCE).
Поиск элементов Max и Min массива в JavaScript.
Вы можете использовать несколько подходов:
С использованием
Math.min()
и
Math.max()
let array = [100, 0, 50];
Math.min(...array); // 0
Math.max(...array); // 100
С использованиемSorting
let array = [100, 0, 50];
arraySorted = array.toSorted((a, b) => a - b); // [0, 50, 100];
arraySorted.at(0); // 0
arraySorted.at(-1); // 100
Использование простого цикла for
let array = [100, 0, 50];
let maxNumber = array[0];
let minNumber = array[0];
for (let i = 1; i < array.length; i++) {
if (array[i] > maxNumber) {
maxNumber = array[i];
}
if (array[i] < minNumber) {
minNumber = array[i];
}
}