我有一个数组:

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

我无法更改阵列的结构。我收到了一个45的id,我想得到数组中该对象的“bar”。

如何在JavaScript或使用jQuery实现这一点?


当前回答

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

其他回答

上述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解决方案比基于对象{}(L)的解决方案快得多令人惊讶的是,Safari上基于对象{}的小型阵列解决方案(L)比传统的(E)慢令人惊讶的是,Firefox上基于Map(K)的小阵列解决方案比传统的(E)慢

搜索对象始终存在时的结论

使用传统for(E)的解决方案对于小阵列最快,对于大阵列最快对于大型阵列,使用缓存(J)的解决方案是最快的,而对于小型阵列,则是中等速度基于find(A)和findIndex(B)的解决方案对于小阵列很快,对于大阵列则很快基于$.map(H)的解决方案在小型阵列上是最慢的基于reduce(D)的解决方案在大型阵列上最慢

搜索对象从不存在时的结论

基于传统for(E)的解决方案在小型和大型阵列上都是最快的(除了Chrome小型阵列,后者速度第二快)基于reduce(D)的解决方案在大型阵列上最慢使用缓存(J)的解决方案是中等速度的,但如果我们将具有空值的键也保存在缓存中,则可以加快速度(这里没有这样做,因为我们希望避免在搜索许多不存在的键时在缓存中无限制地消耗内存)

细节

对于解决方案

无需预先计算:ABCDEFGH我J(J解决方案使用“内部”缓存,其速度取决于搜索元素重复的频率)带有预先计算KL

我进行了四次测试。在测试中,我希望在10次循环迭代中找到5个对象(对象ID在迭代过程中不会改变)-所以我调用测试方法50次,但只有前5次具有唯一的ID值:

小数组(10个元素)和搜索对象始终存在-您可以在此处执行大数组(10k个元素)和搜索对象始终存在-您可以在此处执行小数组(10个元素)和搜索对象从不存在-您可以在此处执行大数组(10k个元素)和搜索对象从不存在-您可以在这里执行

测试代码如下

函数A(arr,id){返回arr.find(o=>o.id==id);}函数B(arr,id){设idx=arr.findIndex(o=>o.id==id);返回arr[idx];}函数C(arr,id){返回arr.filter(o=>o.id==id)[0];}函数D(arr,id){return arr.reduce((a,b)=>(a.id==id&&a)||(b.id==id&&b));}函数E(arr,id){对于(var i=0;i<arr.length;i++)如果(arr[i].id==id)返回arr[i];返回null;}函数F(arr,id){var retObj={};$.each(arr,(索引,obj)=>{如果(obj.id==id){retObj=对象;return false;}});返回retObj;}函数G(arr,id){return$.grep(arr,e=>e.id==id)[0];}函数H(arr,id){return$.map(myArray,函数(val){返回val.id==id?val:空;})[0];}函数I(arr,id){return _.find(arr,o=>o.id==id);}设J=(()=>{let cache=new Map();返回函数J(arr,id,el=null){返回cache.get(id)||(el=arr.find(o=>o.id==id),cache.set(id,el),el);}})();函数K(arr,id){return mapK.get(id)}函数L(arr,id){返回mapL[id];}// -------------//测试// -------------console.log('查找id=5');myArray=[…Array(10)].map((x,i)=>({'id':`${i}`,'foo':`bar_${i}`));const mapK=新地图(myArray.Map(el=>[el.id,el]));常量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('hole 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>此代码段仅显示经过测试的代码

搜索对象始终存在的小数组的Chrome测试结果示例

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

如果找到,则返回object元素,否则为false

由于您已经在使用jQuery,因此可以使用grep函数来搜索数组:

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

结果是找到项的数组。如果您知道对象始终存在,并且它只出现一次,那么只需使用result[0].foo获取值。否则,应检查结果数组的长度。例子:

if (result.length === 0) {
  // no result found
} else if (result.length === 1) {
  // property found, access the foo property using result[0].foo
} else {
  // multiple items found
}

下面的代码将帮助您从数据中的嵌套对象中搜索值。

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