在 JavaScript 对象数组中通过 id 查找对象

2117

我有一个数组:

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

我无法更改数组的结构。我正在传递一个id参数 45,我想获取该数组中该对象的'bar'值。

如何在JavaScript或使用jQuery实现?

37个回答

29

As others have pointed out, .find() is the way to go when looking for one object within your array. However, if your object cannot be found using this method, your program will crash:

const myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
const res = myArray.find(x => x.id === '100').foo; // Uh oh!
/*
Error:
"Uncaught TypeError: Cannot read property 'foo' of undefined"
or in newer chrome versions:
Uncaught TypeError: Cannot read properties of undefined (reading 'foo')
*/

通过在使用.foo之前检查.find()的结果是否定义,可以解决此问题。现代JS使我们可以轻松地使用可选链式调用来实现这一点,如果找不到对象,则返回undefined而不是使您的代码崩溃:

const myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
const res = myArray.find(x => x.id === '100')?.foo; // No error!
console.log(res); // undefined when the object cannot be found


26

如果您多次执行此操作,则可以设置一个 Map(ES6):

const map = new Map( myArray.map(el => [el.id, el]) );

然后您可以简单地进行O(1)查找:

map.get(27).foo

18
你可以很容易地使用 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/


1
我忘记了jQuery的map自动删除null元素这一事实。对我来说,这听起来很误导人,并且与“map”的常见概念不同,因为结果的长度与原始集合不同。 - MaxArt

17

使用本地 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


请注意,Array.reduce在IE8及以下版本中不受支持。 - Burn_E99

16
虽然有很多正确的答案,但很多答案没有提到这是一个不必要的昂贵操作,如果执行多次会导致实际性能问题。在现实世界中,如果您处理了大量的项目并且性能是一个问题,最好的方法是一开始就构建一个查找表。
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


16

你可以使用筛选器,

  function getById(id, myArray) {
    return myArray.filter(function(obj) {
      if(obj.id == id) {
        return obj 
      }
    })[0]
  }

get_my_obj = getById(73, myArray);

2
@TobiasBeuving - 使用Array.find()的方法也是纯JS,而且应该会在第一次找到匹配项时停止搜索,因此效率更高。 - Adrian Lynch

9

最近,我需要从一个巨大的数组中搜索字符串,这是同样的问题。

经过一些搜索,我发现用简单的代码处理会很容易:

代码:

var items = mydata.filter(function(item){
    return item.word.toLowerCase().startsWith( 'gk );
})

请查看 https://jsfiddle.net/maheshwaghmare/cfx3p40v/4/

Serach from 20k strings


8
你可以尝试使用http://sugarjs.com/中的Sugarjs。
它有一个非常甜美的数组方法,.find。因此,你可以像这样查找元素:
array.find( {id: 75} );

你可以传递一个对象,并在它上面添加更多属性来增加另一个“where-clause”。
请注意,Sugarjs扩展了本地对象,一些人认为这非常邪恶......

2
嗯,它确实是邪恶的,因为新的EcmaScript版本可能会引入具有相同名称的新方法。而猜猜看,这正是find发生的情况。我的建议是,如果你想扩展本地原型,请始终使用更具体的名称,将最简单的名称留给未来的标准开发。 - MaxArt
这个评论已经快两年了,今天我宁愿使用lodash。不过如果你想的话,你可以在sugarjs网站上阅读关于这个主题的内容。他们对你的观点持有很好的立场:http://sugarjs.com/native - deepflame
1
该操作要求使用JavaScript或jQuery解决方案。 - Tobias Beuving

8

遍历数组中的任何项。对于您访问的每个项目,请检查该项目的id。如果它是匹配的,则返回它。

如果您只想要代码:

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

7
我们可以使用Jquery方法$.each()/$.grep()
var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}

或者
var data = $.grep(array, function( n, i ) {
  return ( n !== 5 && i > 4 );
});

使用ES6语法:

Array.find, Array.filter, Array.forEach, Array.map

或者使用 Lodash https://lodash.com/docs/4.17.10#filter 或 Underscore https://underscorejs.org/#filter


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接