通过JavaScript对象数组中的id查找对象

我有一个数组:

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

我无法改变数组的结构。 我被传递了一个45的ID,我想获得数组中的对象的'bar'

我如何在JavaScript或使用jQuery做到这一点?

由于您已经在使用jQuery,因此可以使用用于search数组的grep函数:

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

结果是一个包含find的项目的数组。 如果你知道这个对象总是存在并且只发生一次,那么你可以使用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 } 

另一个解决scheme是创build一个查找对象:

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

如果你需要做很多的查找,这个特别有趣。

这将不需要更多的内存,因为ID和对象将被共享。

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

来自MDN:

如果数组中的元素满足提供的testing函数,则find()方法将返回数组中的值。 否则返回undefined


如果您想要获取匹配元素的数组,请改为使用filter()方法:

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

这将返回对象的数组。 如果你想获得foo属性的数组,你可以用map()方法做到这一点:

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

注意:旧的浏览器(例如IE 11)不支持像find()filter()和箭头函数这样的方法,所以如果你想支持这些浏览器,你应该使用Babel来编译你的代码。

Underscore.js有一个很好的方法:

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

我认为最简单的方法如下,但在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 

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

尝试以下

 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; } 
 myArray.filter(function(a){ return a.id == some_id_you_want })[0] 

上面的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'); 

你可以使用filter,

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

你可以使用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/

使用本机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) }); 

返回对象元素,如果find,否则返回false

虽然在这里有许多正确的答案,但是其中许多人没有解决这样的事实,即如果这样做不止一次,这是不必要的昂贵的操作。 在极端情况下,这可能是真正性能问题的原因。

在现实世界中,如果您正在处理大量项目并且性能受到关注,那么最初构build查找会快得多:

 var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}]; var lookup = items.reduce((o,i)=>o[i.id]=o,{}); 

然后你可以像这样在固定的时间得到物品:

 var bar = o[id]; 

您也可以考虑使用Map而不是对象作为查找: https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

您可以尝试从http://sugarjs.com/ Sugarjs。

它在数组上有一个非常可爱的方法, .find 。 所以你可以find这样的元素:

 array.find( {id: 75} ); 

你也可以传递一个具有更多属性的对象来添加另一个“where-clause”。

请注意,Sugarjs扩展了本地对象,有些人认为这是非常邪恶的…

即使在纯JavaScript中也可以通过使用内置的数组的“filter”函数来实现:

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

所以现在简单地通过“id”代替key和“45”代替value ,你会得到完整的对象匹配一个45的ID。所以这将是,

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

下面是我如何在纯JavaScript中进行操作,以我能想到的ECMAScript 3或更高版本中最简单的方式。 只要find匹配,它就会返回。

 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' 

build立在接受的答案上:

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 

我真的很喜欢Aaron Digulla提供的答案,但需要保留我的对象数组,以便以后可以遍历它。 所以我修改它

  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 

迭代数组中的任何项目。 对于您访问的每个项目,请检查该项目的ID。 如果是匹配,请将其退回。

如果你只是想要codez:

 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]; } 

使用:

 var retObj ={}; $.each(ArrayOfObjects, function (index, obj) { if (obj.id === '5') { // id.toString() if it is int retObj = obj; return false; } }); return retObj; 

它应该通过ID返回一个对象。

只要浏览器支持ECMA-262 ,第5版(2009年12月),这应该工作,几乎是一线:

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

这个解决scheme也可能有帮助:

 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 ,如果find一个对象, 函数将返回对象,而不是一个数组。

使用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; }); } 

如果你多次这样做,你可以设置一个地图(ES6):

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

那么你可以简单地做:

 map.get(27).foo 

从aggaton的答案开始 ,这是一个实际返回想要的元素的函数(如果没有find,则返回null )给定array和一个callback函数,该函数返回“正确”元素的真值:

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

只要记住,这不会在IE8上本地工作,因为它不支持some 。 一个polyfill可以提供,或者总是经典for循环:

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

它实际上更快,更紧凑。 但是,如果你不想重新发明轮子,我build议使用像下划线或lodash实用程序库。

考虑“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; } 

最短,

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

我的方式来find数组的索引:

 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 

使用jQuery的过滤方法:

  $(myArray).filter(function() { return this.id == desiredId; }).first(); 

这将返回具有指定Id的第一个元素。

它也有一个很好的C#LINQ查看格式的好处。