У меня есть массив объектов. Их достаточно большое количество.
Объекты вида:
{
id: 123,
name: 'г. Москва"
}
Как мне быстро найти среди них объект (он гарантировано будет один), свойство name
которого совпадает с моим указанным (например, “г. Москва”) и взять его id
? Нужен самый оптимальный и быстрый способ.
br3t
4,3794 золотых знака16 серебряных знаков29 бронзовых знаков
задан 13 июл 2017 в 19:53
Как оказалось, не все помнят про существование в ES6 метода find. 🙂
let cities = [{ id: 121, name: 'г. Урюпинск' }, { id: 122, name: 'г. Париж' }, { id: 123, name: 'г. Москва' }, { id: 124, name: 'г. Штормград' }];
let searchTerm = 'г. Москва';
let cityId = cities.find(city => city.name === searchTerm).id
console.log(cityId);
ответ дан 13 июл 2017 в 20:45
YaantYaant
4,4031 золотой знак16 серебряных знаков24 бронзовых знака
Самым быстрым способом будет создание объекта с ключами-name и доставать просто по ключу.
Если нужно достать именно из массива, то создать 2 массив со значениями name из первого в той же последовательности. После этого искать нужный индекс с помощью indexOf
и по нему доставать нужный объект.
Но самым простым и читаемым вариантом(но более медленным по сравнению с предыдущими) будет filter
. Он быстрее перебора массива с помощью for...in
/for...of
.
ответ дан 13 июл 2017 в 20:06
SapphironSapphiron
9155 серебряных знаков12 бронзовых знаков
Если ECMAScript – то через Array.filter:
var data = [{ id: 123, name: "г. Москва" }, { id: 124, name: "г. Немосква" }];
var cutySearch = "г. Москва";
var cityId = data.filter(function(val) {
return val.name == cutySearch;
})[0].id;
console.log(cityId);
Либо вручную перебирать:
var data = [{ id: 123, name: "г. Москва" }, { id: 124, name: "г. Немосква" }];
var cutySearch = "г. Москва";
var cityId;
for(var i = 0; i < data.length; i++) {
if(data[i].name == cutySearch) {
cityId = data[i].id;
break;
}
}
console.log(cityId);
ответ дан 13 июл 2017 в 20:02
br3tbr3t
4,3794 золотых знака16 серебряных знаков29 бронзовых знаков
6
OK, there are few ways to do that, but let’s start with the simplest one and latest approach to do this, this function is called find()
.
Just be careful when you using find
to as even IE11 dosn’t support it, so it needs to be transpiled…
so you have this object as you said:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
and you can write a function and get it like this:
function filterValue(obj, key, value) {
return obj.find(function(v){ return v[key] === value});
}
and use the function like this:
filterValue(jsObjects, "b", 6); //{a: 5, b: 6}
Also in ES6 for even shortened version:
const filterValue = (obj, key, value)=> obj.find(v => v[key] === value);
This method only return the first value which match…, for better result and browser support, you can use filter
:
const filterValue = (obj, key, value)=> obj.filter(v => v[key] === value);
and we will return [{a: 5, b: 6}]
…
This method will return an array instead…
You simpley use for loop as well, create a function like this:
function filteredArray(arr, key, value) {
const newArray = [];
for(i=0, l=arr.length; i<l; i++) {
if(arr[i][key] === value) {
newArray.push(arr[i]);
}
}
return newArray;
}
and call it like this:
filteredArray(jsObjects, "b", 6); //[{a: 5, b: 6}]
В этом посте мы обсудим, как определить, содержит ли массив объект с заданным атрибутом в JavaScript.
1. Использование some()
метод
Рекомендуемое решение — использовать some() метод, возвращающий true, если в массиве найден хотя бы один объект, удовлетворяющий заданному условию, и false в противном случае.
Следующий пример демонстрирует это, находя человека, живущего в штате NYC
.
const people = [ { name : ‘Jane Smith’, city : ‘New York City’, state : ‘NYC’, zip : ‘10001’ }, { name : ‘Bob Brown’, city : ‘Colorado’, state : ‘CO’, zip : ‘80011’ }, { name : ‘Alice Brown’, city : ‘Michigan’, state : ‘MI’, zip : ‘48002’ } ]; const isPresent = people.some(e => e.state === ‘NYC’); console.log(isPresent); /* результат: true */ |
Скачать Выполнить код
2. Использование find()
метод
Другим решением является использование find() метод, который возвращает первый экземпляр объекта в массиве, который удовлетворяет данному тесту или undefined
если он не найден.
const people = [ { name : ‘Jane Smith’, city : ‘New York City’, state : ‘NYC’, zip : ‘10001’ }, { name : ‘Bob Brown’, city : ‘Colorado’, state : ‘CO’, zip : ‘80011’ }, { name : ‘Alice Brown’, city : ‘Michigan’, state : ‘MI’, zip : ‘48002’ } ]; const isPresent = people.find(e => e.state === ‘NYC’) !== undefined; console.log(isPresent); /* результат: true */ |
Скачать Выполнить код
3. Использование findIndex()
метод
В качестве альтернативы вы можете использовать findIndex() метод, аналогичный методу find()
метод, за исключением того, что он возвращает индекс первого экземпляра объекта или -1
если объект не найден.
const people = [ { name : ‘Jane Smith’, city : ‘New York City’, state : ‘NYC’, zip : ‘10001’ }, { name : ‘Bob Brown’, city : ‘Colorado’, state : ‘CO’, zip : ‘80011’ }, { name : ‘Alice Brown’, city : ‘Michigan’, state : ‘MI’, zip : ‘48002’ } ]; const isPresent = people.findIndex(e => e.state === ‘NYC’) !== –1; console.log(isPresent); /* результат: true */ |
Скачать Выполнить код
4. Использование filter()
метод
Другой вероятный способ — отфильтровать массив, чтобы вернуть все объекты, соответствующие заданному условию. Это можно легко сделать с помощью filter() метод.
const people = [ { name : ‘Jane Smith’, city : ‘New York City’, state : ‘NYC’, zip : ‘10001’ }, { name : ‘Bob Brown’, city : ‘Colorado’, state : ‘CO’, zip : ‘80011’ }, { name : ‘Alice Brown’, city : ‘Michigan’, state : ‘MI’, zip : ‘48002’ } ]; const isPresent = people.filter(e => e.state === ‘NYC’).length > 0; console.log(isPresent); /* результат: true */ |
Скачать Выполнить код
5. Использование forEach()
метод
Наконец, вы можете выполнить итерацию по массиву, используя forEach() метод и проверьте наличие объекта в массиве.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
const people = [ { name : ‘Jane Smith’, city : ‘New York City’, state : ‘NYC’, zip : ‘10001’ }, { name : ‘Bob Brown’, city : ‘Colorado’, state : ‘CO’, zip : ‘80011’ }, { name : ‘Alice Brown’, city : ‘Michigan’, state : ‘MI’, zip : ‘48002’ } ]; var isPresent = false; people.forEach(o => { if (e => e.state === ‘NYC’) { isPresent = true; } }); console.log(isPresent); /* результат: true */ |
Скачать Выполнить код
Это все о проверке, содержит ли массив объект с заданным атрибутом в JavaScript.
Array.prototype.find()
Метод find()
возвращает первый элемент предоставленного массива, который удовлетворяет предоставленной функции тестирования. Если никакие значения не удовлетворяют функции тестирования, возвращается значение undefined
.
Try it
- Если вам нужен индекс найденного элемента в массиве, используйте
findIndex()
. - Если вам нужно найти индекс значения , используйте
indexOf()
. (Это похоже наfindIndex()
, но проверяет каждый элемент на равенство со значением вместо использования функции проверки.) - Если вам нужно узнать, существует ли значение в массиве, используйте
includes()
. Опять же, он проверяет каждый элемент на равенство со значением вместо использования функции проверки. - Если вам нужно найти, удовлетворяет ли какой-либо элемент предоставленной функции тестирования, используйте
some()
.
Syntax
find((element) => { } ) find((element, index) => { } ) find((element, index, array) => { } ) find(callbackFn) find(callbackFn, thisArg) find(function(element) { }) find(function(element, index) { }) find(function(element, index, array){ }) find(function(element, index, array) { }, thisArg)
Parameters
callbackFn
-
Функция для выполнения над каждым значением в массиве.
Функция вызывается со следующими аргументами:
element
-
Текущий элемент в массиве.
index
-
Индекс (позиция)текущего элемента в массиве.
array
-
Массив , что
find
была призвана.
Обратный вызов должен возвращать истинное значение, чтобы указать, что соответствующий элемент был найден.
-
thisArg
Optional -
Объект для использования в качестве
this
внутриcallbackFn
.
Return value
Первый элемент в массиве, который удовлетворяет предоставленной функции тестирования. В противном случае возвращается undefined
Description
Метод find
выполняет функцию callbackFn
один раз для каждого индекса массива, пока callbackFn
не вернет истинное значение. Если это так, find
немедленно возвращает значение этого элемента. В противном случае find
возвращает значение undefined
.
callbackFn
вызывается для каждого индекса массива, а не только для тех, которым присвоены значения. Это означает, что он может быть менее эффективным для разреженных массивов по сравнению с методами, которые обращаются только к присвоенным значениям.
Если thisArg
параметр при условии , чтобы find
, он будет использоваться в качестве this
значения внутри каждого вызова callbackFn
. Если он не указан, используется undefined
.
Метод find
не изменяет массив, в котором он вызывается, но функция, предоставленная callbackFn
, может. Если это так, элементы, обрабатываемые функцией find
, устанавливаются перед первым вызовом callbackFn
. Следовательно:
-
callbackFn
не будет посещать какие-либо элементы, добавленные в массив после начала вызоваfind
. - Элементы, которые назначены индексам, которые уже посещены, или индексам за пределами диапазона,
callbackFn
не будут посещены . - Если существующий, еще не посещенный элемент массива изменяется с помощью
callbackFn
, его значение, переданное вcallbackFn
, будет значением в то время, когдаfind
посещает индекс этого элемента. - Элементы, которые были
deleted
, по-прежнему посещаются.
Предупреждение: одновременное изменение типа, описанного в предыдущем абзаце, часто приводит к трудному для понимания коду, и, как правило, его следует избегать (за исключением особых случаев).
Examples
Найти объект в массиве по одному из его свойств
const inventory = [ {name: 'apples', quantity: 2}, {name: 'bananas', quantity: 0}, {name: 'cherries', quantity: 5} ]; function isCherries(fruit) { return fruit.name === 'cherries'; } console.log(inventory.find(isCherries));
Использование стрелочной функции и деструктуризации
const inventory = [ {name: 'apples', quantity: 2}, {name: 'bananas', quantity: 0}, {name: 'cherries', quantity: 5} ]; const result = inventory.find(({ name }) => name === 'cherries'); console.log(result)
Найти простое число в массиве
В следующем примере выполняется поиск элемента в массиве, который является простым числом (или возвращается undefined
, если простого числа нет):
function isPrime(element, index, array) { let start = 2; while (start <= Math.sqrt(element)) { if (element % start++ < 1) { return false; } } return element > 1; } console.log([4, 6, 8, 12].find(isPrime)); console.log([4, 5, 8, 12].find(isPrime));
Следующие примеры показывают , что не существует , а удаленные элементы будут посещенных и что значение передается функции обратного вызова их значение при посещении:
const array = [0,1,,,,5,6]; array.find((value, index) => { console.log('Visited index ', index, ' with value ', value); }); array.find((value, index) => { if (index === 0) { console.log('Deleting array[5] with value ', array[5]); delete array[5]; } console.log('Visited index ', index, ' with value ', value); });
Specifications
Browser compatibility
Desktop | Mobile | Server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox для Android | Opera Android | Safari на IOS | Samsung Internet | Deno | Node.js | |
find |
45 |
12 |
25 |
No |
32 |
8 |
45 |
45 |
4 |
32 |
8 |
5.0 |
1.0 |
4.0.0 0.12.0 |
See also
- Полифилл
Array.prototype.find
вcore-js
-
Array.prototype.findIndex()
— найти и вернуть индекс -
Array.prototype.includes()
— проверяет, существует ли значение в массиве. -
Array.prototype.filter()
— удалить все несоответствующие элементы -
Array.prototype.every()
— проверить все элементы -
Array.prototype.some()
— тестировать до совпадения одного элемента
JavaScript
-
Array.prototype.fill()
Метод fill()изменяет все элементы в массиве на статическое значение,начиная с начального индекса (по умолчанию 0)и заканчивая длиной массива (array.length).
-
Array.prototype.filter()
Метод filter()создает неглубокую копию заданного массива порций,отфильтрованную до элементов,прошедших тест,реализованный предоставленной функцией.
-
Array.prototype.findIndex()
Метод findIndex()возвращает в качестве первого элемента массив,удовлетворяющий заданной функции тестирования.
-
Array.prototype.findLast()
Метод findLast()возвращает значение элемента массива,который удовлетворяет заданной функции тестирования.
Содержание
- 1 Array.includes() — есть ли элемент в массиве
- 2 Array.indexOf() — индекс элемента в массиве
- 3 Array.find() — найти элемент по условию
- 4 Array.findIndex() — найти индекс элемента в массиве
- 5 Поиск всех совпадений в массиве
- 6 Поиск в массиве объектов
- 7 Заключение
Для поиска по массиву в JavaScript существует несколько методов прототипа Array, не считая что поиск можно выполнить и методами для перебора массива и в обычном цикле.
Итак, мы сегодня рассмотрим следующие варианты:
- Array.includes()
- Array.indexOf()
- Array.find()
- Array.findIndex()
- Array.filter()
- Array.forEach()
Array.includes() — есть ли элемент в массиве
Данный метод ищет заданный элемент и возвращает true
или false
, в зависимости от результата поиска. Принимает два параметра:
element
— то, что мы будем искатьfromIndex
(необязательный) — с какого индекса начинать поиск. По умолчанию с 0.
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry'];
console.log(arr.includes('Apple')); // true
console.log(arr.includes('Apple', 1)); // false
Как видно из примера выше, в первом случае мы получим true
, т.к. начали с нулевого элемента массива. Во втором случае мы передали второй параметр — индекс, с которого нужно начать поиск — и получили false
, т.к. дальше элемент не был найден.
Array.indexOf() — индекс элемента в массиве
Данный метод, в отличие от предыдущего, возвращает индекс первого найденного совпадения. В случае если элемент не найден, будет возвращено число -1
Также принимает два параметра:
element
— элемент, который мы будем искатьfromIndex
(необязательный) — с какого индекса начинать поиск. По умолчанию с 0.
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
console.log(arr.indexOf('Apple')); // 0
console.log(arr.indexOf('Apple', 1)); // 4
console.log(arr.indexOf('Orange', 2)); // -1
Как видно из примера выше, в первом случае мы получаем 0, т.к. сразу нашли первый элемент массива (первое совпадение, дальше поиск уже не выполняется). Во втором случае 4, т.к. начали поиск с индекса 1 и нашли следующее совпадение. В третьем примере мы получили результат -1, т.к. поиск начали с индекса 2, а элемент Orange в нашем массиве под индексом 1.
Так как данный метод возвращает индекс или -1, мы можем присвоить результат в переменную для дальнейшего использования:
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
const index = arr.indexOf('Lemon');
if (index !== -1) {
// сделать что-то
}
Чтобы произвести какие-то действия над найденным элементом массива, мы можем использовать следующий синтаксис:
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
const index = arr.indexOf('Lemon');
arr[index] = 'Lime'; // заменяем найденный элемент
console.log(arr)ж // ['Apple', 'Orange', 'Lime', 'Cherry', 'Apple']
Примеры использования данного метода вы можете также найти в посте про удаление элемента из массива
Array.find() — найти элемент по условию
Данный метод callback
и thisArg
в качестве аргументов и возвращает первое найденное значение.
Callback принимает несколько аргументов:
item — текущий элемент массива
index — индекс текущего элемента
currentArray — итерируемый массив
Пример использования:
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
const apple = arr.find(item => item === 'Apple');
console.log(apple); // Apple
Данный метод полезен тем, что мы можем найти и получить сразу и искомый элемент, и его index
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
let indexOfEl;
const apple = arr.find((item, index) => {
if (item === 'Apple') {
indexOfEl = index;
return item;
}
});
console.log(apple, indexOfEl); // Apple 0
Также работа кода прекратиться как только будет найден нужный элемент и второй элемент (дубликат) не будет найден.
В случае если ничего не найдено будет возвращен undefined
.
Array.findIndex() — найти индекс элемента в массиве
Этот метод похож на метод find()
, но возвращать будет только индекс элемента, который соответствует требованию. В случае, если ничего не найдено, вернет -1
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
const index = arr.findIndex(item => item === 'Apple');
console.log(index); // 0
Ну и по аналогии с предыдущим методом, поиск завершается после первого совпадения.
Поиск всех совпадений в массиве
Метод filter()
кроме всего остального также можно использовать для поиска по массиву. Предыдущие методы останавливаются при первом соответствии поиска, а данный метод пройдется по массиву до конца и найдет все элементы. Но данный метод вернет новый массив, в который войдут все элементы соответствующие условию.
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
const filteredArr = arr.filter(item => item === 'Apple');
console.log(filteredArr); // ['Apple', 'Apple']
console.log(arr); // ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
Как видите из примера выше, первоначальный массив не будет изменен.
Подробнее про метод JS filter() можете прочитать в этом посте.
Для этих же целей можно использовать метод forEach(), который предназначен для перебора по массиву:
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
let indexes = [];
arr.forEach((item, index) => {
if (item === 'Apple') indexes.push(index)
});
console.log(indexes); // [0, 4]
В массив indexes
мы получили индексы найденных элементов, это 0 и 4 элементы. Также в зависимости от вашей необходимости, можно создать объект, где ключом будет индекс, а значением сам элемент:
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
let arrObjMap = {};
arr.forEach((item, index) => {
if (item === 'Apple') {
arrObjMap[index] = item;
}
});
console.log(arrObjMap); // {0: 'Apple', 4: 'Apple'}
Поиск в массиве объектов
Если у вас массив состоит не из примитивных типов данных, а к примеру, каждый элемент это объект со своими свойствами и значениями, тогда можно использовать следующие варианты для получения индекса элемента.
Первый способ. С использованием метода map
для массива
const arr = [
{ name: 'Ben', age: 21 },
{ name: 'Clif', age: 22 },
{ name: 'Eric', age: 18 },
{ name: 'Anna', age: 27 },
];
const index = arr.map(item => item.name).indexOf('Anna');
console.log(index); //3
console.log(arr[index]); // {name: 'Anna', age: 27}
В данном случае по массиву arr мы проходим и на каждой итерации из текущего элемента (а это объект со свойствами name
и age
) возвращаем имя человека в новый массив и сразу же выполняем поиск по новому массиву на имя Anna. При совпадении нам будет возвращен индекс искомого элемента в массиве.
Второй способ. Данный вариант будет немного проще, т.к. мы можем сразу получить индекс при совпадении:
const index = arr.findIndex(item => item.name === 'Anna');
console.log(index); //3
console.log(arr[index]); // {name: 'Anna', age: 27}
Заключение
Как видите любой из вышеприведенных методов можно использовать для поиска по массиву. Какой из них использовать зависит от вашей задачи и того, что вам нужно получить — сам элемент или его индекс в массиве, найти только первое совпадение или все совпадения при поиске.