Find object by id in an array of JavaScript objects
我有一个阵列:
1 | myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.] |
我无法更改数组的结构。我正在被传递一个
如何在JavaScript或使用jQuery中实现这一点?
由于您已经在使用jquery,因此可以使用grep函数来搜索数组:
1 | var result = $.grep(myArray, function(e){ return e.id == id; }); |
结果是一个包含找到的项的数组。如果您知道对象总是在那里,并且只发生一次,那么您可以使用
1 2 3 4 5 6 7 | if (result.length == 0) { // not found } else if (result.length == 1) { // access the foo property using result[0].foo } else { // multiple items found } |
使用
1 | myArray.find(x => x.id === '45').foo; |
来自MDN:
The
find() method returns a value in the array, if an element in the array satisfies the provided testing function. Otherwiseundefined is returned.
如果要查找其索引,请使用
1 | myArray.findIndex(x => x.id === '45'); |
来自MDN:
The
findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.
如果要获取匹配元素的数组,请改用
1 | myArray.filter(x => x.id === '45'); |
这将返回一个对象数组。如果要获取
1 | myArray.filter(x => x.id === '45').map(x => x.foo); |
旁注:像
另一种解决方案是创建查找对象:
1 2 3 4 5 6 | 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和对象将被共享。
EcmaScript 2015在数组上提供find()方法:
1 2 3 4 | var myArray = [ {id:1, name:"bob <div class="suo-content">[collapse title=""]<ul><li>可能是因为它看起来仍然很有实验性,而且没有多少浏览器支持它,developer.mozilla.org/en-us/docs/web/javascript/reference/&hellip;</li><li>这可以简化为<wyn>myArray.find(d=>d.id===45).foo;</wyn>。</li><li>@蓬松的,甚至是埃多克斯1〔2〕。但这是一个旧的答案,它是在ES2015语法之前编写的,现在也得到了很好的支持。@gothdo的答案目前是线程中最新的。</li><li>@如果.find()返回undefined,那么优化会抛出一个错误。所以这个解决方案只能在保证匹配的情况下使用。</li><li>@Herbertters如果你想确保你可以一直检查空值,这将非常容易与可选的链接:<wyn>myArray.find(d => d.id === 45)?.foo</wyn>。</li><li>此解决方案适用于ES6,与IE浏览器不兼容。</li><li>@miladrashidi喜欢的答案是,如果你想要更旧的浏览器支持,有一个polyfill。同样,使用旧的语法也很容易重写。</li></ul>[/collapse]</div><p><center>[wp_ad_camp_1]</center></p><hr><P>.js有一个很好的方法:</P>[cc lang="javascript"]myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.] obj = _.find(myArray, function(obj) { return obj.id == '45' }) |
我认为最简单的方法是如下,但它在Internet Explorer 8(或更早版本)上不起作用:
1 2 3 | var result = myArray.filter(function(v) { return v.id === '45'; // Filter out the appropriate one })[0].foo; // Get result and access the foo property |
尝试以下操作
1 2 3 4 5 6 7 8 | 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; } |
1 | myArray.filter(function(a){ return a.id == some_id_you_want })[0] |
上面findbyid函数的通用和更灵活的版本:
1 2 3 4 5 6 7 8 9 10 11 12 | // 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'); |
使用map()函数可以很容易地得到:
1 2 3 4 5 6 7 | 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/
你可以使用过滤器,
1 2 3 4 5 6 7 8 9 | function getById(id, myArray) { return myArray.filter(function(obj) { if(obj.id == id) { return obj } })[0] } get_my_obj = getById(73, myArray); |
使用本地
1 2 | var array = [ {'id':'73' ,'foo':'bar'} , {'id':'45' ,'foo':'bar'} , ]; var id = 73; |
1 2 3 | var found = array.reduce(function(a, b){ return (a.id==id && a) || (b.id == id && b) }); |
如果找到,则返回对象元素,否则返回
虽然这里有许多正确的答案,但其中许多答案并没有说明这样一个事实,即如果多次执行此操作,将是一个不必要的昂贵操作。在极端情况下,这可能是导致实际性能问题的原因。
在现实世界中,如果处理的项目很多,并且性能是一个问题,那么最初构建查找会更快:
1 2 3 | var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}]; var lookup = items.reduce((o,i)=>o[i.id]=o,{}); |
然后,您可以在固定时间内获取项目,如下所示:
1 | var bar = o[id]; |
您还可以考虑使用映射而不是对象作为查找:https://developer.mozilla.org/en/docs/web/javascript/reference/global_objects/map
如果多次执行此操作,则可以设置地图(ES6):
1 | const map = new Map( myArray.map(el => [el.id, el]) ); |
然后你可以简单地做:
1 | map.get(27).foo |
以下是我在纯JavaScript中的实现方式,在EcmaScript 3或更高版本中,这是我能想到的最简单的方式。一旦找到匹配项,它就会返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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' |
基于公认的答案:
jQuery:
1 2 | var foo = $.grep(myArray, function(e){ return e.id === foo_id}) myArray.pop(foo) |
或咖啡描述:
1 2 | foo = $.grep myArray, (e) -> e.id == foo_id myArray.pop foo |
你可以在http://sugarjs.com/上试用sugarjs。
它在数组上有一个非常好的方法,
1 | array.find( {id: 75} ); |
您还可以将具有更多属性的对象传递给它,以添加另一个"WHERE子句"。
注意,SugarJS扩展了本地对象,有些人认为这非常邪恶…
您甚至可以在纯JavaScript中使用内置的数组"filter"函数来实现这一点:
1 2 3 | Array.prototype.filterObjects = function(key, value) { return this.filter(function(x) { return x[key] === value; }) } |
现在只需将"id"替换为
1 | myArr.filterObjects("id","45"); |
迭代数组中的任何项。对于您访问的每个项目,请检查该项目的ID。如果匹配,请将其返回。
如果你只想得到编码:
1 2 3 4 5 6 7 8 | 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的数组方法也一样:
1 2 3 4 5 6 7 8 | 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]; } |
使用
演示:https://jsfiddle.net/sumitridhal/r0cz0w5o/4/
杰森
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 } } ]; |
滤波器
1 2 3 4 5 | var getPerson = function(name){ return jsonObj.filter(function(obj) { return obj.name === name; }); } |
更通用、更简短
1 2 3 4 5 | function findFromArray(array,key,value) { return array.filter(function (element) { return element[key] == value; }).shift(); } |
在你的例子中,如
As long as the browser supports ECMA-262, 5th edition (December 2009), this should work, almost one-liner:
1 2 3 | var bFound = myArray.some(function (obj) { return obj.id === 45; }); |
我真的很喜欢Aaron Digulla提供的答案,但是我需要保留我的对象数组,以便稍后迭代。所以我把它改成
1 2 3 4 5 6 7 | 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 |
用途:
1 2 3 4 5 6 7 8 9 10 | 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 2 3 4 5 6 7 8 9 10 | 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"); |
我做得和
最短的,
1 | var theAnswerObj = _.findWhere(array, {id : 42}); |
将"axesOptions"视为对象格式为:field_type=>2,:fields=>[1,3,4]
1 2 3 4 5 6 7 8 | function getFieldOptions(axesOptions,choice){ var fields=[] axesOptions.each(function(item){ if(item.field_type == choice) fields= hashToArray(item.fields) }); return fields; } |
我们可以使用jquery方法$.each()/$.grep())
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}
或
return ( n !== 5 && i > 4 );
});
使用ES6语法:
或者使用lodash https://lodash.com/docs/4.17.10过滤器,下划线https://underlinejs.org/过滤器
从Aggaton的答案开始,这是一个函数,它实际上返回所需元素(如果找不到,则返回
1 2 3 4 5 6 7 8 9 | function findElement(array, callback) { var elem; return array.some(function(e) { if (callback(e)) { elem = e; return true; } }) ? elem : null; }); |
请记住,这在IE8-上并不适用,因为它不支持
1 2 3 4 5 | function findElement(array, callback) { for (var i = 0; i < array.length; i++) if (callback(array[i])) return array[i]; return null; }); |
它实际上更快更紧凑。但是如果你不想重新发明轮子,我建议你使用一个实用程序库,比如下划线或者lodash。
使用jquery的过滤方法:
1 2 3 4 | $(myArray).filter(function() { return this.id == desiredId; }).first(); |
它将返回具有指定ID的第一个元素。
它还有一个不错的C Linq格式的好处。