13

Получить объект JavaScript из массива объектов по значению свойства

12

У меня есть массив из четырех объектов:

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 ответ(ов)

1

Я не понимаю, почему вы против использования цикла 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;
      }
    }
  }
}
0

Есть несколько способов сделать это, но давайте начнем с самого простого и современного подхода, который использует функцию 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}]
0

Вы можете использовать метод _.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.

0

Если вам нужно получить один результат вместо массива, я бы предложил использовать метод reduce.

Вот пример решения на обычном JavaScript, который возвращает соответствующий объект, если он существует, или null, если нет:

var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);

Этот код проходит по массиву arr и ищет объект, у которого свойство b равно 6. Если такой объект найден, он будет возвращен, иначе будет возвращено значение null.

0

Да, вы правильно поняли, вы хотите найти объект в массиве, у которого свойство 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.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь