Как я могу легко получить минимальный или максимальный элемент массива JavaScript?
Пример Psuedocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
javascript
HankH
источник
источник
...
) сMath.max()
так:Math.max(...[2, 5, 16, 1])
. Смотрите мой ответ, сделанный из документации MDN .Math.max.apply(null, [2,5,16,1])
Ответы:
Как насчет увеличения встроенного объекта Array для использования
Math.max
/Math.min
вместо:Вот JSFiddle .
Расширение встроенных модулей может привести к конфликтам с другими библиотеками (некоторые видят), поэтому вам может быть удобнее просто
apply
подключитьсяMath.xxx()
к массиву напрямую:В качестве альтернативы, если ваш браузер поддерживает ECMAScript 6, вы можете использовать оператор распространения, который работает аналогично
apply
методу:источник
null
илиMath
или{}
или что-либо кapply()
или неcall()
имеет никакого отношения к результату.Math.max
не имеет и не должно ссылаться наthis
внутреннюю.Math.max.apply(null, $.makeArray(array));
.max
или.min
метод в будущем. Совершенно реалистичный сценарий: вы используете этот ответ. В 2016 году ES7 или ES8 спецArray.max
иArray.min
. В отличие от этой версии, они работают на строках. Ваш будущий коллега пытается получить последнюю алфавитную строку в массиве с хорошо документированным теперь родным.max()
методом, но таинственным образом получаетNaN
. Через несколько часов она находит этот код, запускаетgit blame
и проклинает ваше имя.Для полного обсуждения см .: http://aaroncrane.co.uk/2008/11/javascript_max_api/
источник
Math.max.apply(Math, array)
иMath.max.apply(null, array)
? В блоге написано «... вы также должны излишне повторять, чтоmax
принадлежитMath
...», но, похоже, мне не нужно это делать (устанавливая первый аргументapply
asnull
).Math.max(a,b)
,Math
передается какthis
значение, поэтому имеет смысл сделать то же самое при вызове сapply
. НоMath.max
не используетthis
значение, поэтому вы можете передать любое значение, которое вы хотите.Для больших массивов (~ 10⁷ элементов),
Math.min
иMath.max
оба выдают следующую ошибку в Node.js.Более надежное решение - не добавлять каждый элемент в стек вызовов, а вместо этого передавать массив:
Если вас беспокоит скорость, следующий код работает примерно в 3 раза быстрее, чем
Math.max.apply
на моем компьютере. Смотрите http://jsperf.com/min-and-max-in-array/2 .Если ваши массивы содержат строки вместо чисел, вам также необходимо преобразовать их в числа. Приведенный ниже код делает это, но он замедляет код ~ 10 раз на моей машине. Смотрите http://jsperf.com/min-and-max-in-array/3 .
источник
min
иmax
последнему элементу и уменьшите количество итераций на 1 (while(--len)
);)very different results
Вы сделали это 5 лет спустя)reduce
решение является самым медленным. Даже если вы работаете с массивом, содержащим миллионы элементов, лучше использовать стандартный цикл for . Смотрите мой ответ для более.Использование оператора распространения (ES6)
Показать фрагмент кода
источник
If no arguments are given, the result is -∞.
ТЛ; др
Решение MDN
В официальном MDN документы на
Math.max()
уже охватывают этот вопрос:Максимальный размер массива
По MDN на
apply
и распространение решений было ограничение 65536, прилагаемой от предела максимального количества аргументов:Они даже предоставляют гибридное решение, которое на самом деле не имеет хорошей производительности по сравнению с другими решениями. Смотрите тест производительности ниже.
В 2019 году фактическим пределом является максимальный размер стека вызовов . Для современных настольных браузеров на базе Chromium это означает, что когда дело доходит до нахождения минимума / максимума с использованием
apply
или распространением, практически максимальный размер для массивов только с числами составляет ~ 120000 . Выше этого произойдет переполнение стека и будет выдана следующая ошибка:С помощью приведенного ниже сценария (на основе этого сообщения в блоге ), уловив эту ошибку, вы можете рассчитать предел для вашей конкретной среды.
Предупреждение! Запуск этого скрипта занимает много времени, и в зависимости от производительности вашей системы он может замедлить или привести к сбою вашего браузера / системы!
Производительность на больших массивах
Основываясь на тесте в комментарии EscapeNetscape , я создал несколько тестов, которые тестируют 5 различных методов на массиве случайных чисел только с 100000 элементов .
В 2019 году результаты показывают, что стандартный цикл (который, кстати, не имеет ограничения по размеру) является самым быстрым во всем мире.
apply
и распространение идет за ним, затем гораздо позже гибридное решение MDN, тоreduce
самое медленное.Почти все тесты дали одинаковые результаты, за исключением одного, где спред почему-то оказался самым медленным.
Если вы увеличите свой массив до 1 миллиона элементов, все начнет ломаться, и вы останетесь со стандартным циклом в качестве быстрого решения и
reduce
более медленного.Тест JSPerf
Тест JSBen
Тест JSBench.me
Исходный код теста
Показать фрагмент кода
источник
Math.max.apply(Math, arr)
для максимальной совместимости.(...)
иapply
будут либо давать сбой, либо возвращать неправильный результат, если в массиве слишком много элементов [...] Решение для сокращения не имеет этой проблемы». При тестировании Chrome, FF, Edge и IE11 кажется, что это хорошо для массива до 100 тыс. значений. (Проверено на Win10 и последних браузерах: Chrome 110k, Firefox 300k, Edge 400k, IE11 150k).Если вы, как и я, параноики по поводу использования
Math.max.apply
(что может привести к ошибкам при использовании больших массивов в соответствии с MDN ), попробуйте следующее:Или в ES6:
К сожалению, анонимные функции необходимы (вместо того, чтобы использовать,
Math.max.bind(Math)
потому чтоreduce
они не только передаютa
иb
его функции, но такжеi
и ссылку на сам массив, поэтому мы должны убедиться, что мы не пытаемся вызыватьmax
их тоже).источник
Math.max(...array)
?apply
, и, следовательно, имеет те же недостатки (максимальный предел аргумента).function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Math.min()
без указания значений, возвращаетсяInfinity
, так что эти функции могут использовать,reduce(..., Infinity)
чтобы соответствовать этому поведению. Я предпочитаю, чтобы он генерировал исключение, хотя (как это происходит в настоящее время), потому что принятие минимума пустого массива, вероятно, будет ошибкой..apply
часто используется, когда целью является вызов переменной функции со списком значений аргументов, напримерMath.max([value1[,value2, ...]])
Функция возвращает наибольшее из нуля или более чисел.Math.max()
Метод не позволяет передавать в массиве. Если у вас есть список значений, из которых вам нужно получить наибольшее, вы обычно вызываете эту функцию с помощью Function.prototype.apply () , напримерОднако, начиная с ECMAScript 6, вы можете использовать оператор распространения :
Используя оператор распространения, вышеприведенное можно переписать так:
При вызове функции с использованием оператора переменной, вы можете даже добавить дополнительные значения, например
Бонус:
Оператор Spread позволяет использовать синтаксис литерала массива для создания новых массивов в ситуациях , когда в ES5 вам нужно будет падать обратно императивный код, используя комбинацию
push
,splice
и т.д.источник
concat
большинством программистов, потому что он позволяет вам поддерживать стиль одной линии.Два способа короче и проще:
Способ 1 :
Способ 2 :
источник
0
вы можете использовать[0].concat(arr)
или с расширенным синтаксисом[0, ...arr]
(вместо 'arr')Вы делаете это путем расширения типа Array:
Усиленный отсюда (Джон Резиг)
источник
Простое решение для нахождения минимального значения над
Array
элементом состоит в использованииArray
функции prototypereduce
:или используя встроенную в JavaScript функцию Math.Min () (спасибо @Tenflex):
Это наборы
min
кA[0]
, а затем проверяет ,A[1]...A[n]
является ли он строго меньше , чем токmin
. ЕслиA[i] < min
затемmin
обновляется доA[i]
. Когда все элементы массива были обработаны,min
возвращается как результат.РЕДАКТИРОВАТЬ : Включить позицию минимального значения:
источник
min
вернуть не только значение, но и его положение в массиве?Другие уже дали некоторые решения, в которых они дополняют
Array.prototype
. Все, что я хочу в этом ответе, чтобы уточнить, должно ли это бытьMath.min.apply( Math, array )
илиMath.min.apply( null, array )
. Так какой контекст следует использовать,Math
илиnull
?При передаче
null
в качестве контекста контекст поapply
умолчанию будет глобальным объектом (window
объектом в случае браузеров). ПередачаMath
объекта в качестве контекста будет правильным решением, но это также не повредит передачеnull
. Вот пример, когдаnull
могут возникнуть проблемы при украшенииMath.max
функции:Выше сгенерирует исключение , потому что
this.foo
будет оцениваться , какwindow.foo
, чтоundefined
. Если мы заменимnull
наMath
, все будет работать как положено, и на экране будет выведена строка «foo» (я проверял это с помощью Mozilla Rhino ).Вы можете в значительной степени предположить, что никто не украсил
Math.max
это, прохождениеnull
будет работать без проблем.источник
Foo.staticMethod
и ссылатьсяthis
? Не будет ли это ошибкой в дизайне декоратора? (если, конечно, они не хотят ссылаться на глобальную область и хотят оставаться независимыми от используемого движка JavaScript, например, Rhino).Math.max
, реализованный согласно спецификации, не используетthis
. Если кто-то переопределяет тоMath.max
, что он используетthis
, то он заставил его поведение нарушать спецификации, и вы должны бросать в них острые предметы. Вы не должны кодировать эту возможность больше, чем кодировать возможность того, что кто-то поменялся местамиMath.max
иMath.min
ради lulz.Еще один способ сделать это:
Применение:
источник
Альтернативные Методы
Math.min
ИMath.max
методы являются рекурсивными операции , которые добавляются в стек вызовов двигателя JS, и , скорее всего , сбой на массив , который содержит большое количество элементов(более ~ 10⁷ пунктов, зависит от браузера пользователя).
Вместо этого используйте что-то вроде этого:
Или с лучшим временем выполнения:
Или чтобы получить и Мин и Макс:
Или с еще лучшим временем выполнения *:
* Протестировано с 1 000 000 элементов:
просто для справки, время выполнения первой функции (на моей машине) составило 15,84 мс против 2-й функции всего лишь 4,32 мс.
источник
Это может удовлетворить ваши цели.
источник
comparer
предполагается назвать в какой - то конкретной области? Потому что, как это ссылки,this[index]
которыеundefined
всегда.Math.xxx
) будет работать в глобальной области видимости ...https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
это сработало для меня.
источник
Я удивлен, что никто не упомянул функцию уменьшения.
источник
Для больших массивов (~ 10⁷ элементов)
Math.min
иMath.max
запускает RangeError (превышен максимальный размер стека вызовов) в файле node.js.Для больших массивов быстрое и грязное решение:
источник
У меня была та же проблема, мне нужно было получить минимальное и максимальное значения массива и, к моему удивлению, не было встроенных функций для массивов. Прочитав много, я решил самостоятельно протестировать «топ-3» решения:
Тестовый код был таким:
Массив A был заполнен 100 000 случайных целых чисел, каждая функция была выполнена 10 000 раз на Mozilla Firefox 28.0 на настольном компьютере Intel Pentium 4 2.99 ГГц с Windows Vista. Время указывается в секундах, получаемых функцией performance.now (). Результаты были такими, с 3 дробными цифрами и стандартным отклонением:
Раствор REDUCE был на 117% медленнее, чем дискретный раствор. Раствор APPLY оказался хуже, на 2118% медленнее, чем дискретный раствор. Кроме того, как заметил Питер, он не работает для больших массивов (около 1 000 000 элементов).
Кроме того, чтобы завершить тесты, я протестировал этот расширенный дискретный код:
Время: среднее = 0,218 с, сд = 0,094
Таким образом, он на 35% медленнее, чем простое дискретное решение, но одновременно извлекает как максимальные, так и минимальные значения (для их извлечения любому другому решению потребуется как минимум вдвое больше). Как только ОП потребуются оба значения, дискретное решение будет лучшим выбором (даже если две отдельные функции, одна для расчета максимума, а другая для вычисления минимума, они превзойдут второе лучшее, решение REDUCE).
источник
Вы можете использовать следующую функцию в любом месте вашего проекта:
И тогда вы можете вызвать функции, передающие массив:
источник
Следующий код работает для меня:
источник
Итерируйте, отслеживая, как вы идете.
Это оставит мин / макс пустым, если в массиве нет элементов. Устанавливает min и max за один проход, если в массиве есть какие-либо элементы.
Вы также можете расширить Array с помощью
range
метода, описанного выше, для повторного использования и улучшения читабельности. Смотрите рабочую скрипку на http://jsfiddle.net/9C9fU/Используется как
источник
range
функции, которая была бы лучшим способом получить как минимальное, так и максимальное значение IMO одновременно - как я сделал с обновлением своего ответа.Я думал, что поделюсь своим простым и понятным решением.
Для мин:
И для макс:
источник
for…in
перечисления для массивов!Простые вещи, правда.
источник
Вот один из способов получить максимальное значение из массива объектов. Создайте копию (со срезом), затем отсортируйте копию по убыванию и возьмите первый элемент.
источник
Используя
Math.max()
илиMath.min()
Следующая функция используется
Function.prototype.apply()
для поиска максимального элемента в числовом массиве.getMaxOfArray([1, 2, 3])
эквивалентноMath.max(1, 2, 3)
, но вы можете использоватьgetMaxOfArray()
программно построенные массивы любого размера.Или с новым оператором распространения, получить максимум массива становится намного проще.
источник
Помимо использования математической функции max и min, еще одна функция - встроенная функция sort (): здесь мы идем
источник
Решение ChaosPandion работает, если вы используете прототип. Если нет, подумайте об этом:
Выше будет возвращать NaN, если значение массива не является целым числом, поэтому вы должны построить некоторые функции, чтобы избежать этого. В противном случае это будет работать.
источник
Math
объект в качестве контекста?Если вы используете библиотеку sugar.js , вы можете написать arr.min () и arr.max (), как вы предлагаете. Вы также можете получить минимальное и максимальное значения из нечисловых массивов.
Примеры:
Такие библиотеки, как Lo-Dash и underscore.js также предоставляют аналогичные мощные функции min и max:
Пример из Lo-Dash:
источник
источник
Пытаться
Показать фрагмент кода
Для Math.min / max (+ apply) мы получаем ошибку:
Показать фрагмент кода
источник