[英]Find object by id in an array of JavaScript objects
我有一個數組:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]
我無法更改數組的結構。 我被傳遞了一個45
的 id,我想在數組中為那個 object 獲取'bar'
。
我如何在 JavaScript 或使用 jQuery 中執行此操作?
使用
find()<\/code>方法:
myArray.find(x => x.id === '45').foo;
由於您已經在使用 jQuery,您可以使用用於搜索數組的grep<\/a>函數:
var result = $.grep(myArray, function(e){ return e.id == id; });
另一種解決方案是創建一個查找對象:
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
lookup[array[i].id] = array[i];
}
... now you can use lookup[id]...
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
嘗試以下
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');
今天 2020.06.20 我在 Chrome 81.0、Firefox 77.0 和 Safari 13.1 上對 MacOs High Sierra 進行測試,以選擇解決方案。
具有預先計算 (K,L) 的解決方案比其他解決方案快得多,並且不會與它們進行比較 - 可能它們使用了一些特殊的內置瀏覽器優化
Map
(K) 的 Chrome 和 Safari 解決方案比基於 object {}
(L) 的解決方案快得多{}
(L) 的小型數組解決方案比傳統for
(E) 慢Map
(K) 的 Firefox 小數組解決方案比傳統for
(E) 慢for
(E) 的解決方案對於小陣列來說最快,對於大陣列來說速度很快find
(A) 和findIndex
(B) 的解決方案在小型陣列上速度很快,在大型陣列上速度中等$.map
(H) 的解決方案在小型陣列上最慢reduce
(D) 的解決方案在大陣列上最慢for
(E) 的解決方案在小型和大型陣列上最快(Chrome 小型陣列除外,它的速度第二快)reduce
(D) 的解決方案在大陣列上最慢對於解決方案
我進行了四次測試。 在測試中,我想在 10 次循環迭代中找到 5 個對象(對象 ID 在迭代期間不會改變) - 所以我調用測試方法 50 次,但只有前 5 次具有唯一的 id 值:
測試代碼如下
function A(arr, id) { return arr.find(o=> o.id==id); } function B(arr, id) { let idx= arr.findIndex(o=> o.id==id); return arr[idx]; } function C(arr, id) { return arr.filter(o=> o.id==id)[0]; } function D(arr, id) { return arr.reduce((a, b) => (a.id==id && a) || (b.id == id && b)); } function E(arr, id) { for (var i = 0; i < arr.length; i++) if (arr[i].id==id) return arr[i]; return null; } function F(arr, id) { var retObj ={}; $.each(arr, (index, obj) => { if (obj.id == id) { retObj = obj; return false; } }); return retObj; } function G(arr, id) { return $.grep(arr, e=> e.id == id )[0]; } function H(arr, id) { return $.map(myArray, function(val) { return val.id == id ? val : null; })[0]; } function I(arr, id) { return _.find(arr, o => o.id==id); } let J = (()=>{ let cache = new Map(); return function J(arr,id,el=null) { return cache.get(id) || (el=arr.find(o=> o.id==id), cache.set(id,el), el); } })(); function K(arr, id) { return mapK.get(id) } function L(arr, id) { return mapL[id]; } // ------------- // TEST // ------------- console.log('Find id=5'); myArray = [...Array(10)].map((x,i)=> ({'id':`${i}`, 'foo':`bar_${i}`})); const mapK = new Map( myArray.map(el => [el.id, el]) ); const mapL = {}; myArray.forEach(el => mapL[el.id]=el); [A,B,C,D,E,F,G,H,I,J,K,L].forEach(f=> console.log(`${f.name}: ${JSON.stringify(f(myArray, '5'))}`)); console.log('Whole array',JSON.stringify(myArray));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script> This snippet only presents tested codes
搜索對象始終存在的小數組的 Chrome 示例測試結果
如果你多次這樣做,你可以設置一個 Map (ES6):
const map = new Map( myArray.map(el => [el.id, el]) );
這可以通過在使用
.foo<\/code>之前檢查
.find()<\/code>的結果是否已定義來解決。
現代 JS 允許我們通過
可選鏈接<\/a>輕松地做到這一點,如果找不到對象,則返回
undefined<\/code> ,而不是使您的代碼崩潰:
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";
您可以使用過濾器,
function getById(id, myArray) {
return myArray.filter(function(obj) {
if(obj.id == id) {
return obj
}
})[0]
}
get_my_obj = getById(73, myArray);
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
雖然這里有許多正確答案,但其中許多都沒有解決這樣一個事實,即如果多次執行,這將是一項不必要的昂貴操作。 在極端情況下,這可能是真正的性能問題的原因。
在現實世界中,如果您正在處理大量項目並且性能是一個問題,那么最初構建查找會更快:
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var lookup = items.reduce((o,i)=>o[i.id]=o,{});
最近,我不得不面對同樣的事情,我需要從一個巨大的數組中搜索字符串。
經過一番搜索,我發現使用簡單的代碼很容易處理:
代碼:
var items = mydata.filter(function(item){
return item.word.toLowerCase().startsWith( 'gk );
})
您可以從http:\/\/sugarjs.com\/<\/a>試用 Sugarjs。
它在數組上有一個非常好的方法
.find<\/code> 。
所以你可以找到這樣的元素:
array.find( {id: 75} );
只要瀏覽器支持ECMA-262<\/a> ,第 5 版(2009 年 12 月),這應該可以工作,幾乎是單行:
var bFound = myArray.some(function (obj) {
return obj.id === 45;
});
以下是我在純 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'
更通用和簡短
function findFromArray(array,key,value) {
return array.filter(function (element) {
return element[key] == value;
}).shift();
}
遍歷數組中的任何項目。 對於您訪問的每個項目,請檢查該項目的 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];
}
我們可以使用 Jquery 方法
$.each()\/$.grep()<\/code>
var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}
基於公認的答案:
jQuery:
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)
使用
Array.prototype.filter()<\/code>函數。
演示<\/strong>: https<\/a> :\/\/jsfiddle.net\/sumitridhal\/r0cz0w5o\/4\/
JSON<\/strong>
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
}
}
];
您甚至可以在純 JavaScript 中通過使用內置的數組“過濾器”函數來執行此操作:
Array.prototype.filterObjects = function(key, value) {
return this.filter(function(x) { return x[key] === value; })
}
利用:
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {
if (obj.id === '5') { // id.toString() if it is int
retObj = obj;
return false;
}
});
return retObj;
此解決方案也可能有幫助:
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");
我真的很喜歡 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
在這個解決方案中,當我們搜索某個對象時,我們將其保存在緩存中。 這是“始終搜索解決方案”和“在預先計算中為每個對象創建哈希映射”之間的中間點。
let cachedFind = (()=>{ let cache = new Map(); return (arr,id,el=null) => cache.get(id) || (el=arr.find(o=> o.id==id), cache.set(id,el), el); })(); // --------- // TEST // --------- let myArray = [...Array(100000)].map((x,i)=> ({'id':`${i}`, 'foo':`bar_${i}`})); // example usage console.log( cachedFind(myArray,'1234').foo ); // Benchmark let bench = (id) => { console.time ('time for '+id ); console.log ( cachedFind(myArray,id).foo ); // FIND console.timeEnd('time for '+id ); } console.log('----- no cached -----'); bench(50000); bench(79980); bench(99990); console.log('----- cached -----'); bench(79980); // cached bench(99990); // cached
我有一個數組:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]
我無法更改數組的結構。 我被傳遞的 id 為45
,我想在數組中為該對象獲取'bar'
。
如何在 JavaScript 或使用 jQuery 中執行此操作?
下面的代碼將幫助您從數據中的嵌套對象中搜索值。
const updatedData = myArrayOfObjects.filter((obj: any) => Object.values(obj).some((val: any) => {
if (typeof (val) == typeof ("str")) {
return val.toString().includes(Search)
} else {
return Object.values(val).some((newval: any) => {
if (newval !== null) {
return newval.toString().includes(Search)
}
})
}
}))
最短的
var theAnswerObj = _.findWhere(array, {id : 42});
將“ 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;
}
我找到數組索引的方法:
index = myArray.map((i) => i.id).indexOf(value_of_id);
item = myArray[index];
使用jQuery的filter方法:
$(myArray).filter(function()
{
return this.id == desiredId;
}).first();
這將返回具有指定 Id 的第一個元素。
它還具有良好的 C# LINQ 外觀格式的好處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.