通过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查看格式的好处。