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

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

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

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

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

1195
задан 09 сент. '11 в 18:42
источник поделиться
31 ответ
  • 1
  • 2

Используйте метод 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полифоном).

567
ответ дан 15 февр. '16 в 0:11
источник

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

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

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

if (result.length == 0) {
  // not found
} else if (result.length == 1) {
  // access the foo property using result[0].foo
} else {
  // multiple items found
}
1428
ответ дан 09 сент. '11 в 18:54
источник

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

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

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

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

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

346
ответ дан 09 сент. '11 в 18:50
источник

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);

Работает без внешних библиотек. Но если вы хотите более старую поддержку браузера, вы можете включить this polyfill.

154
ответ дан 11 февр. '14 в 1:32
источник

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

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
139
ответ дан 22 нояб. '12 в 15:52
источник

Я думаю, что самый простой способ был бы следующим, но он не будет работать в 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
123
ответ дан 09 сент. '11 в 18:46
источник

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

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;
}
65
ответ дан 09 сент. '11 в 18:45
источник
myArray.filter(function(a){ return a.id == some_id_you_want })[0]
42
ответ дан 16 апр. '15 в 20:31
источник

Общая и более гибкая версия функции 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');
30
ответ дан 13 июля '12 в 23:34
источник

Вы можете легко получить это с помощью функции 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/

14
ответ дан 09 сент. '11 в 18:46
источник

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

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

get_my_obj = getById(73, myArray);
13
ответ дан 13 сент. '13 в 12:43
источник

Использование 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

10
ответ дан 04 июня '15 в 3:13
источник

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

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

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

10
ответ дан 23 марта '16 в 13:24
источник

Вот как я буду заниматься этим в чистом 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'
6
ответ дан 28 февр. '15 в 21:04
источник

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

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
4
ответ дан 23 окт. '14 в 17:23
источник

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

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

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

map.get(27).foo
4
ответ дан 08 авг. '17 в 18:26
источник

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

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

array.find( {id: 75} );

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

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

4
ответ дан 06 нояб. '12 в 11:52
источник

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

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

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];
}
3
ответ дан 09 сент. '11 в 18:46
источник

Вы можете сделать это даже в чистом 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");
3
ответ дан 26 окт. '14 в 7:39
источник

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

var bFound = myArray.some(function (obj) {
    return obj.id === 45;
});
2
ответ дан 08 апр. '14 в 20:14
источник

Используйте функцию 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;
    });
}
2
ответ дан 02 мая '17 в 18:40
источник

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

	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
2
ответ дан 19 нояб. '14 в 6:55
источник

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

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

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

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

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

1
ответ дан 28 февр. '13 в 18:03
источник

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

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, и если один объект обнаружен, функция вернет объект, а не массив.

1
ответ дан 22 окт. '14 в 12:15
источник

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

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

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

0
ответ дан 12 дек. '18 в 9:35
источник

Мы можем использовать методы Jquery $.each()/$. Grep() var data= []; $.each(array,function(i){if(n !== 5 && я > 4){data.push(item)}} var data= []; $.each(array,function(i){if(n !== 5 && я > 4){data.push(item)}}

или же

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

использовать синтаксис ES6: Array.find, Array.filter, Array.forEach, Array.map

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

0
ответ дан 25 сент. '18 в 9:49
источник

Начиная с 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.

0
ответ дан 02 сент. '14 в 15:41
источник

Рассмотрим "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;
}
0
ответ дан 04 марта '15 в 9:06
источник

Кратчайший,

var theAnswerObj = _.findWhere(array, {id : 42});
0
ответ дан 03 янв. '15 в 6:52
источник

Мой способ найти индекс массива:

index = myArray.map(getItemId).indexOf(id);
getItemId: function(item) {
  return item.id;
}

// to get foo property use index
myArray[index].foo

//If you want to use ES6
index = myArray.map((i) => i.id).indexOf(id)
myArray[index].foo
-3
ответ дан 24 мая '16 в 5:28
источник
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос