Найти объект по id в массиве объектов JavaScript

У меня есть массив:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]

Я не могу изменить структуру массива. Мне передается id 45, и я хочу получить 'bar' для этого объекта в массиве.

Как это сделать в JavaScript или с помощью jQuery?

Ответ 1

Используйте метод find():

myArray.find(x => x.id === '45').foo;

От MDN:

Метод find() возвращает первое значение в массиве, если элемент в массиве удовлетворяет предоставленной функции тестирования. В противном случае возвращается undefined.


Если вы хотите найти его индекс, используйте findIndex():

myArray.findIndex(x => x.id === '45');

От MDN:

Метод findIndex() возвращает индекс первого элемента в массиве, который удовлетворяет предоставленной функции тестирования. В противном случае возвращается -1.


Если вы хотите получить массив совпадающих элементов, используйте вместо этого метод filter():

myArray.filter(x => x.id === '45');

Это вернет массив объектов. Если вы хотите получить массив свойств foo, вы можете сделать это с помощью метода map():

myArray.filter(x => x.id === '45').map(x => x.foo);

Примечание: такие методы, как find() или filter() и функции стрелок, не поддерживаются более старыми браузерами (например, IE), поэтому, если вы хотите поддерживать эти браузеры, вы должны перенести свой код с помощью Babelполифилом).

Ответ 2

Поскольку вы уже используете jQuery, вы можете использовать функцию grep, которая предназначена для поиска в массиве:

var result = $.grep(myArray, function(e){ return e.id == id; });

В результате получается массив с найденными элементами. Если вы знаете, что объект всегда присутствует и что он встречается только один раз, вы можете просто использовать result[0].foo, чтобы получить значение. В противном случае вы должны проверить длину полученного массива. Пример:

if (result.length === 0) {
  // no result found
} else if (result.length === 1) {
  // property found, access the foo property using result[0].foo
} else {
  // multiple items found
}

Ответ 3

Другим решением является создание объекта поиска:

var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
    lookup[array[i].id] = array[i];
}

... now you can use lookup[id]...

Это особенно интересно, если вам нужно много искать.

Это не потребует гораздо больше памяти, так как идентификаторы и объекты будут совместно использоваться.

Ответ 4

ECMAScript 2015 предоставляет метод find() на массивах:

var myArray = [
 {id:1, name:"bob"},
 {id:2, name:"dan"},
 {id:3, name:"barb"},
]

// grab the Array item which matchs the id "2"
var item = myArray.find(item => item.id === 2);

// print
console.log(item.name);

Ответ 5

Underscore.js имеет хороший способ для этого:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })

Ответ 6

Я думаю, что самый простой способ был бы следующим, но он не будет работать в Internet Explorer 8 (или ранее):

var result = myArray.filter(function(v) {
    return v.id === '45'; // Filter out the appropriate one
})[0].foo; // Get result and access the foo property

Ответ 7

Попробуйте выполнить

function findById(source, id) {
  for (var i = 0; i < source.length; i++) {
    if (source[i].id === id) {
      return source[i];
    }
  }
  throw "Couldn't find object with id: " + id;
}

Ответ 8

myArray.filter(function(a){ return a.id == some_id_you_want })[0]

Ответ 9

Общая и более гибкая версия функции findById выше:

// array = [{key:value},{key:value}]
function objectFindByKey(array, key, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
    return null;
}

var array = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var result_obj = objectFindByKey(array, 'id', '45');

Ответ 10

Вы можете легко получить это с помощью функции map():

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];

var found = $.map(myArray, function(val) {
    return val.id == 45 ? val.foo : null;
});

//found[0] == "bar";

Рабочий пример: http://jsfiddle.net/hunter/Pxaua/

Ответ 11

Вы можете использовать фильтры,

  function getById(id, myArray) {
    return myArray.filter(function(obj) {
      if(obj.id == id) {
        return obj 
      }
    })[0]
  }

get_my_obj = getById(73, myArray);

Ответ 12

Несмотря на то, что здесь много правильных ответов, многие из них не учитывают тот факт, что это излишне дорогостоящая операция, если она выполняется более одного раза. В крайнем случае это может быть причиной реальных проблем с производительностью.

В реальном мире, если вы обрабатываете множество элементов, а производительность - это гораздо быстрее, чем первоначально построить поиск:

var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];

var lookup = items.reduce((o,i)=>o[i.id]=o,{});

вы можете получить элементы в фиксированное время следующим образом:

var bar = o[id];

Вы также можете использовать карту вместо объекта в качестве поиска: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

Ответ 13

Использование native Array.reduce

var array = [ {'id':'73' ,'foo':'bar'} , {'id':'45' ,'foo':'bar'} , ];
var id = 73;
var found = array.reduce(function(a, b){
    return (a.id==id && a) || (b.id == id && b)
});

возвращает элемент объекта, если найден, иначе false

Ответ 14

Вот как я буду заниматься этим в чистом JavaScript, самым минимальным образом я могу подумать об этом, который работает в ECMAScript 3 или новее. Он возвращается, как только будет найдено совпадение.

var getKeyValueById = function(array, key, id) {
    var testArray = array.slice(), test;
    while(test = testArray.pop()) {
        if (test.id === id) {
            return test[key];
        }
    }
    // return undefined if no matching id is found in array
    return;
}

var myArray = [{'id':'73', 'foo':'bar'}, {'id':'45', 'foo':'bar'}]
var result = getKeyValueById(myArray, 'foo', '45');

// result is 'bar', obtained from object with id of '45'

Ответ 15

Если вы делаете это несколько раз, вы можете настроить карту (ES6):

const map = new Map( myArray.map(el => [el.id, el]) );

Тогда вы можете просто сделать:

map.get(27).foo

Ответ 16

Вы можете попробовать Sugarjs из http://sugarjs.com/.

Он имеет очень сладкий метод в массивах, .find. Итак, вы можете найти такой элемент:

array.find( {id: 75} );

Вы также можете передать объект с большим количеством свойств, чтобы добавить другое "where-clause".

Обратите внимание, что Sugarjs расширяет родные объекты, а некоторые люди считают это очень злым...

Ответ 17

Основываясь на принятом ответе:

JQuery

var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)

Или CoffeeScript:

foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo

Ответ 18

Более общий и короткий

function findFromArray(array,key,value) {
        return array.filter(function (element) {
            return element[key] == value;
        }).shift();
}

в вашем случае Ex. var element = findFromArray(myArray,'id',45), который даст вам весь элемент.

Ответ 19

Итерации по любому элементу массива. Для каждого элемента, который вы посещаете, проверьте этот элемент. Если это совпадение, верните его.

Если вам просто нужен код:

function getId(array, id) {
    for (var i = 0, len = array.length; i < len; i++) {
        if (array[i].id === id) {
            return array[i];
        }
    }
    return null; // Nothing found
}

И то же самое, используя методы массива ECMAScript 5 Array:

function getId(array, id) {
    var obj = array.filter(function (val) {
        return val.id === id;
    });

    // Filter returns an array, and we just want the matching item.
    return obj[0];
}

Ответ 20

Пока браузер поддерживает ECMA-262, 5-е издание (декабрь 2009 г.), это должно работать почти с одним слоем:

var bFound = myArray.some(function (obj) {
    return obj.id === 45;
});

Ответ 21

Вы можете сделать это даже в чистом JavaScript, используя встроенную функцию "filter" для массивов:

Array.prototype.filterObjects = function(key, value) {
    return this.filter(function(x) { return x[key] === value; })
}

Итак, вместо "t22 > вместо" t22 "вместо" t21 "и" 45 "вы просто передадите" id ", и вы получите полный объект, соответствующий идентификатору 45. Таким образом, это будет

myArr.filterObjects("id", "45");

Ответ 22

Используйте функцию Array.prototype.filter().

DEMO: https://jsfiddle.net/sumitridhal/r0cz0w5o/4/

JSON

var jsonObj =[
 {
  "name": "Me",
  "info": {
   "age": "15",
   "favColor": "Green",
   "pets": true
  }
 },
 {
  "name": "Alex",
  "info": {
   "age": "16",
   "favColor": "orange",
   "pets": false
  }
 },
{
  "name": "Kyle",
  "info": {
   "age": "15",
   "favColor": "Blue",
   "pets": false
  }
 }
];

ФИЛЬТР

var getPerson = function(name){
    return jsonObj.filter(function(obj) {
      return obj.name === name;
    });
}

Ответ 23

Мне очень понравился ответ, предоставленный Аароном Дигуллой, но мне нужно было сохранить свой массив объектов, чтобы потом продолжить его. Поэтому я изменил его на

	var indexer = {};
	for (var i = 0; i < array.length; i++) {
	    indexer[array[i].id] = parseInt(i);
	}
	
	//Then you can access object properties in your array using 
	array[indexer[id]].property

Ответ 24

Использование:

var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {

        if (obj.id === '5') { // id.toString() if it is int

            retObj = obj;
            return false;
        }
    });
return retObj;

Он должен возвращать объект по id.

Ответ 25

Это решение может также помочь:

Array.prototype.grep = function (key, value) {
    var that = this, ret = [];
    this.forEach(function (elem, index) {
        if (elem[key] === value) {
            ret.push(that[index]);
        }
    });
    return ret.length < 2 ? ret[0] : ret;
};
var bar = myArray.grep("id","45");

Я сделал это точно так же, как $.grep, и если один объект обнаружен, функция вернет объект, а не массив.

Ответ 26

Начиная с aggaton answer, это функция, которая фактически возвращает желаемый элемент (или null, если не найден), учитывая array и a callback, которая возвращает правдивое значение для "правильного" элемента:

function findElement(array, callback) {
    var elem;
    return array.some(function(e) {
        if (callback(e)) {
            elem = e;
            return true;
        }
    }) ? elem : null;
});

Просто помните, что это не работает на IE8, поскольку оно не поддерживает some. A polyfill может быть предусмотрен, альтернативно всегда существует классический цикл for:

function findElement(array, callback) {
    for (var i = 0; i < array.length; i++)
        if (callback(array[i])) return array[i];
    return null;
});

Это на самом деле быстрее и компактнее. Но если вы не хотите изобретать колесо, я предлагаю использовать библиотеку служебных программ, например, подчеркивание или lodash.

Ответ 27

Мы можем использовать методы Jquery $.each()/$.grep()

var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}

или

var data = $.grep(array, function( n, i ) {
  return ( n !== 5 && i > 4 );
});

использовать синтаксис ES6:

Array.find, Array.filter, Array.forEach, Array.map

Или используйте Lodash https://lodash.com/docs/4.17.10#filter, Подчеркни https://underscorejs.org/#filter

Ответ 28

В последнее время мне приходится сталкиваться с тем же, что и при поиске строки из огромного массива.

После некоторого поиска я обнаружил, что это будет легко сделать с помощью простого кода:

Код:

var items = mydata.filter(function(item){
    return item.word.toLowerCase().startsWith( 'gk );
})

См. Https://jsfiddle.net/maheshwaghmare/cfx3p40v/4/

Serach from 20k strings

Ответ 29

Кратчайший,

var theAnswerObj = _.findWhere(array, {id : 42});

Ответ 30

Рассмотрим "axesOptions" как массив объектов с форматом объекта, являющимся {: field_type = > 2,: fields = > [1,3,4]}

function getFieldOptions(axesOptions,choice){
  var fields=[]
  axesOptions.each(function(item){
    if(item.field_type == choice)
        fields= hashToArray(item.fields)
  });
  return fields;
}