Получить объект JavaScript из массива объектов по значению свойства
У меня есть массив из четырех объектов:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
Мне нужно получить третий объект ({a: 5, b: 6}
) по значению свойства b
, например, без использования цикла for...in
. Есть ли способ сделать это более элегантно?
Заранее спасибо за помощь!
5 ответ(ов)
Я не понимаю, почему вы против использования цикла for
(предположительно, вы имели в виду просто for
, а не конкретно for..in
), они быстрые и легкие для чтения. В любом случае, вот несколько вариантов.
Цикл for:
function getByValue(arr, value) {
for (var i = 0, iLen = arr.length; i < iLen; i++) {
if (arr[i].b == value) return arr[i];
}
}
.filter
function getByValue2(arr, value) {
var result = arr.filter(function(o) { return o.b == value; });
return result ? result[0] : null; // или undefined
}
.forEach
function getByValue3(arr, value) {
var result = [];
arr.forEach(function(o) { if (o.b == value) result.push(o); });
return result ? result[0] : null; // или undefined
}
Если же вы действительно имели в виду for..in
и хотите найти объект с любым свойством, равным 6, то вам стоит использовать for..in
, если только вы не передали имена для проверки.
Пример
function getByValue4(arr, value) {
var o;
for (var i = 0, iLen = arr.length; i < iLen; i++) {
o = arr[i];
for (var p in o) {
if (o.hasOwnProperty(p) && o[p] == value) {
return o;
}
}
}
}
Есть несколько способов сделать это, но давайте начнем с самого простого и современного подхода, который использует функцию find()
.
Однако будьте осторожны с использованием find
, так как даже IE11 не поддерживает её, и вам может понадобиться транспиляция...
Итак, у вас есть следующий объект:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
Вы можете написать функцию и получить результат следующим образом:
function filterValue(obj, key, value) {
return obj.find(function(v) { return v[key] === value; });
}
И использовать функцию так:
filterValue(jsObjects, "b", 6); // {a: 5, b: 6}
Также в ES6 вы можете написать более краткий вариант:
const filterValue = (obj, key, value) => obj.find(v => v[key] === value);
Этот метод вернет только первое значение, которое соответствует условию. Для лучшего результата и более широкой поддержки браузеров вы можете использовать filter
:
const filterValue = (obj, key, value) => obj.filter(v => v[key] === value);
В этом случае мы получим [{a: 5, b: 6}]
.
Этот метод вернет массив.
Также вы можете использовать простой цикл for
, создав функцию, например, так:
function filteredArray(arr, key, value) {
const newArray = [];
for (let i = 0, l = arr.length; i < l; i++) {
if (arr[i][key] === value) {
newArray.push(arr[i]);
}
}
return newArray;
}
И вызывать её следующим образом:
filteredArray(jsObjects, "b", 6); // [{a: 5, b: 6}]
Вы можете использовать метод _.findWhere
из библиотеки underscore.js
, чтобы найти объект в массиве объектов, который соответствует заданному критерию. Вот пример кода:
var foundObject = _.findWhere(jsObjects, { b: 6 });
В данном случае, jsObjects
— это массив объектов, а { b: 6 }
— это критерий поиска. Метод _.findWhere
вернёт первый объект, у которого свойство b
равно 6. Если такого объекта не найдено, вернётся undefined
.
Если вам нужно найти все объекты, соответствующие критериям, вы можете использовать _.filter
:
var foundObjects = _.filter(jsObjects, { b: 6 });
Этот код вернёт массив всех объектов, в которых свойство b
равно 6.
Если вам нужно получить один результат вместо массива, я бы предложил использовать метод reduce
.
Вот пример решения на обычном JavaScript, который возвращает соответствующий объект, если он существует, или null
, если нет:
var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
Этот код проходит по массиву arr
и ищет объект, у которого свойство b
равно 6. Если такой объект найден, он будет возвращен, иначе будет возвращено значение null
.
Да, вы правильно поняли, вы хотите найти объект в массиве, у которого свойство b
равно 6
. В вашем примере проверка выполняется с помощью метода some
. Вот как это можно сделать:
var found;
jsObjects.some(function (obj) {
if (obj.b === 6) {
found = obj;
return true;
}
});
Этот код перебирает массив jsObjects
и сохраняет объект в переменной found
, если его свойство b
равно 6
. Метод some
вернет true
, как только будет найдено совпадение.
Если вы используете библиотеку Underscore.js, вы можете сделать это немного иначе:
var found = _.select(jsObjects, function (obj) {
return obj.b === 6;
});
В этом случае _.select
(или _.filter
в версии Underscore.js) вернет массив объектов, соответствующих условию. Если вам нужен только первый найденный объект, вы также можете использовать _.find
:
var found = _.find(jsObjects, function (obj) {
return obj.b === 6;
});
Этот вариант вернет первый объект, у которого свойство b
равно 6
.
Сортировка массива объектов по значению строкового свойства
Как получить уникальные значения из массива объектов в JavaScript?
Как перемешать (сделать случайным) массив в JavaScript?
Как объединить два массива в JavaScript и удалить дубликаты?
Как удалить все дубликаты из массива объектов?