Мне интересно, есть ли известный, встроенный / элегантный способ найти первый элемент массива JS, соответствующий заданному условию. Эквивалентом AC # будет List.Find .
До сих пор я использовал двухфункциональную комбинацию, подобную этой:
// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
if (typeof predicateCallback !== 'function') {
return undefined;
}
for (var i = 0; i < arr.length; i++) {
if (i in this && predicateCallback(this[i])) return this[i];
}
return undefined;
};
// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
return (typeof (o) !== 'undefined' && o !== null);
};
И тогда я могу использовать:
var result = someArray.findFirst(isNotNullNorUndefined);
Но поскольку в ECMAScript так много методов массивов функционального стиля , возможно, что-то уже есть? Я полагаю, что многие люди должны все время реализовывать подобные вещи ...
javascript
arrays
Якуб П.
источник
источник
return (typeof (o) !== 'undefined' && o !== null);
до этогоreturn o != null;
. Они в точности эквивалентны.Ответы:
Начиная с ES6 существует нативный
find
метод для массивов; это останавливает перечисление массива, как только он находит первое совпадение и возвращает значение.Старый ответ:
Я должен опубликовать ответ, чтобы остановить эти
filter
предложения :-)Вы можете использовать
some
метод Array для итерации массива до тех пор, пока не будет выполнено условие (и затем остановитесь). К сожалению, он вернет только то, было ли условие выполнено один раз, а не по какому элементу (или по какому индексу) оно было выполнено. Поэтому мы должны немного изменить его:источник
some()
с другой стороны, возвращается немедленно, что намного быстрее почти во всех случаях, чем фильтрация решений.Начиная с ECMAScript 6, вы можете использовать
Array.prototype.find
для этого. Это реализовано и работает в Firefox (25.0), Chrome (45.0), Edge (12) и Safari (7.1), но не в Internet Explorer или ряде других старых или необычных платформ .Например, выражение ниже оценивается как
106
.Если вы хотите использовать это прямо сейчас, но нуждаетесь в поддержке IE или других неподдерживающих браузеров, вы можете использовать прокладку. Я рекомендую шим es6 . MDN также предлагает шимм, если по какой-то причине вы не хотите использовать весь эс6 шим в своем проекте. Для максимальной совместимости вы хотите использовать es6-shim, потому что в отличие от версии MDN он обнаруживает ошибочные собственные реализации
find
и перезаписывает их (см. Комментарий, который начинается «Обойти ошибки в Array # find и Array # findIndex» и строки, следующие непосредственно за ней) ,источник
find
лучше, чем,filter
так какfind
останавливается немедленно, когда находит элемент, соответствующий условию, в то время какfilter
циклически перебирает все элементы, чтобы получить все соответствующие элементы.Как насчет использования фильтра и получения первого индекса из полученного массива?
источник
.shift
здесь?shift
том, что оно «выглядит умным», но на самом деле более запутанно. Кто бы мог подумать, что вызовshift()
без аргументов будет таким же, как и первый элемент? Непонятно ИМО. В любом случае доступ к массиву быстрее: jsperf.com/array-access-vs-shift.shift()
перед[0]
явно указанным, как это. Несмотря на это, это альтернатива, которую вы можете использовать или нет, но я бы придерживался[0]
.К настоящему времени должно быть ясно, что JavaScript не предлагает такого решения изначально; Вот два ближайших производных, самый полезный первый:
Array.prototype.some(fn)
предлагает желаемое поведение остановки при выполнении условия, но возвращает только наличие элемента; нетрудно применить некоторые хитрости, такие как решение, предложенное ответом Берги .Array.prototype.filter(fn)[0]
делает для отличного однострочного, но наименее эффективным, потому что вы выбрасываетеN - 1
элементы только для того, чтобы получить то, что вам нужно.Традиционные методы поиска в JavaScript характеризуются возвращением индекса найденного элемента вместо самого элемента или -1. Это избавляет от необходимости выбирать возвращаемое значение из домена всех возможных типов; индекс может быть только числом, а отрицательные значения недопустимы.
Оба решения выше не поддерживают поиск смещения, поэтому я решил написать это:
источник
Резюме:
ES6
find()
find()
расположенArray.prototype
таким образом, чтобы его можно было использовать в каждом массиве.find()
принимает обратный вызов, когдаboolean
проверяется условие Функция возвращает значение (не индекс!)Пример:
источник
Если вы используете,
underscore.js
вы можете использовать егоfind
иindexOf
функции, чтобы получить именно то, что вы хотите:Документация:
источник
По состоянию на ES 2015,
Array.prototype.find()
обеспечивает эту точную функциональность.Для браузеров, которые не поддерживают эту функцию, в Mozilla Developer Network предусмотрена поли-заливка (вставлено ниже):
источник
Array.prototype.find () делает именно это, больше информации: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
источник
источник
Я получил вдохновение из нескольких источников в Интернете, чтобы получить решение ниже. Хотел принять во внимание как некоторые значения по умолчанию, так и предоставить способ сравнения каждой записи для общего подхода, который решается.
Использование: (давая значение "Второй")
Реализация:
источник
В Javascript нет встроенной функции для выполнения этого поиска.
Если вы используете JQuery, вы можете сделать
jQuery.inArray(element,array)
.источник
$.inArray
не возвращает логическое значение, а (удивительно!) Возвращает индекс первого соответствующего элемента. Тем не менее, он по-прежнему не выполняет то, о чем просил ОП.Менее элегантный способ, который будет обрабатывать
throw
все правильные сообщения об ошибках (на основеArray.prototype.filter
), но прекратит повторять первый результат:Тогда примеры
Это работает, заканчивая
filter
использованиемthrow
.источник