簡體   English   中英

在 JavaScript 個對象的數組中按 id 查找 object

[英]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]...

Underscore.js<\/a>有一個很好的方法:

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) 的解決方案快得多
  • 令人驚訝的是,Safari 上基於 object {} (L) 的小型數組解決方案比傳統for (E) 慢
  • 令人驚訝的是,基於Map (K) 的 Firefox 小數組解決方案比傳統for (E) 慢

搜索對象始終存在時的結論

  • 使用傳統for (E) 的解決方案對於小陣列來說最快,對於大陣列來說速度很快
  • 使用緩存 (J) 的解決方案對於大型陣列來說是最快的 - 令人驚訝的是,對於小型陣列來說是中等速度
  • 基於find (A) 和findIndex (B) 的解決方案在小型陣列上速度很快,在大型陣列上速度中等
  • 基於$.map (H) 的解決方案在小型陣列上最慢
  • 基於reduce (D) 的解決方案在大陣列上最慢

在此處輸入圖像描述

搜索對象從不存在時的結論

  • 基於傳統for (E) 的解決方案在小型和大型陣列上最快(Chrome 小型陣列除外,它的速度第二快)
  • 基於reduce (D) 的解決方案在大陣列上最慢
  • 使用緩存 (J) 的解決方案是中等速度,但如果我們將具有空值的鍵也保存在緩存中,則可以加快速度(這里沒有這樣做,因為我們希望避免緩存中無限的內存消耗,以防許多不存在的鍵將被搜索)

在此處輸入圖像描述

細節

對於解決方案

  • 沒有預先計算: A B C D E F G H I J (J 解決方案使用“內部”緩存,它的速度取決於搜索元素重復的頻率)
  • 預先計算K L

我進行了四次測試。 在測試中,我想在 10 次循環迭代中找到 5 個對象(對象 ID 在迭代期間不會改變) - 所以我調用測試方法 50 次,但只有前 5 次具有唯一的 id 值:

  • 小數組(10 個元素)和搜索的對象始終存在 - 您可以在此處執行
  • 大數組(10k 個元素)和搜索的對象始終存在 - 您可以在此處執行
  • 小數組(10 個元素)和搜索的對象從不存在 - 你可以在這里執行
  • 大數組(10k 個元素)和搜索的對象從不存在 - 你可以在這里執行

測試代碼如下

 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> ,而不是使您的代碼崩潰:

您可以使用map()<\/a>函數輕松獲得:

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

以下是我在純 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.

相關問題 通過對象的id在javascript數組中查找和移動對象 Javascript,按ID在對象列表中查找對象 在 Javascript 對象數組中查找遞歸(循環)id 如何通過對象數組中的id查找對象? JavaScript將具有相同ID的對象轉換為對象數組 Javascript:使用對象而不是數組按ID檢索對象 如何使用 javascript 從與 id 匹配的對象的遞歸數組中找到 object 並做出反應? JavaScript——在對象數組中找到匹配的對象 JavaScript在對象數組中找到匹配的對象 JavaScript-通過數組中的ID查找對象並進行修改
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM