我有一个阵列:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]
我无法更改数组的结构。我正在传递45
的id,我希望在数组中获得'bar'
该对象。
如何在JavaScript或使用jQuery中执行此操作?
答案 0 :(得分:1437)
由于您已经在使用jQuery,因此可以使用用于搜索数组的grep函数:
var result = $.grep(myArray, function(e){ return e.id == id; });
结果是一个包含找到的项目的数组。如果您知道对象始终存在并且只出现一次,则可以使用result[0].foo
来获取值。否则,您应该检查结果数组的长度。例如:
if (result.length == 0) {
// not found
} else if (result.length == 1) {
// access the foo property using result[0].foo
} else {
// multiple items found
}
答案 1 :(得分:785)
使用find()
方法:
myArray.find(x => x.id === '45').foo;
来自MDN:
如果数组中的元素满足提供的测试函数,则
find()
方法返回数组中的值。否则返回undefined
。
如果您想要找到索引,请使用findIndex()
:
myArray.findIndex(x => x.id === '45');
来自MDN:
findIndex()
方法返回数组中第一个满足提供的测试函数的元素的索引。否则返回-1。
如果您想获得一系列匹配元素,请改用filter()
方法:
myArray.filter(x => x.id === '45');
这将返回一个对象数组。如果您想获得一系列foo
属性,可以使用map()
方法执行此操作:
myArray.filter(x => x.id === '45').map(x => x.foo);
附注:旧版浏览器(如IE)不支持find()
或filter()
和arrow functions等方法,因此如果您想支持这些浏览器,则应将其转换为代码使用Babel(使用polyfill)。
答案 2 :(得分:351)
另一种解决方案是创建一个查找对象:
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和对象将被共享。
答案 3 :(得分:162)
ECMAScript 2015 在数组上提供find()方法:
var myArray = [
{id:1, name:"bob"},
{id:2, name:"dan"},
{id:3, name:"barb"},
]
// grab the Array item which matchs the id "2"
var item = myArray.find(item => item.id === 2);
// print
console.log(item.name);
无需外部库即可运行。但是,如果您想要older browser support,则可能需要包含this polyfill。
答案 4 :(得分:140)
Underscore.js有一个不错的方法:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
答案 5 :(得分:125)
我认为最简单的方法如下,但它不适用于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
答案 6 :(得分:66)
尝试以下
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;
}
答案 7 :(得分:42)
myArray.filter(function(a){ return a.id == some_id_you_want })[0]
答案 8 :(得分:30)
上面的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');
答案 9 :(得分:14)
您可以使用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";
答案 10 :(得分:13)
您可以使用过滤器,
function getById(id, myArray) {
return myArray.filter(function(obj) {
if(obj.id == id) {
return obj
}
})[0]
}
get_my_obj = getById(73, myArray);
答案 11 :(得分:10)
今天2020.06.20我针对选择的解决方案在Chrome 81.0,Firefox 77.0和Safari 13.1的MacOs High Sierra上进行了测试。
具有预计算(K,L)的解决方案比其他解决方案快很多,并且无法与它们进行比较-可能是它们使用了一些特殊的内置浏览器优化
Map
(K)的Chrome和Safari解决方案比基于对象{}
(L)的解决方案要快得多{}
(L)的小型阵列解决方案比传统的for
(E)慢Map
(K)的小型阵列解决方案比传统的for
(E)慢for
(E)的解决方案对于小型阵列最快,而对于大型阵列则最快find
(A)和findIndex
(B)的解决方案对于小型arras而言是快速的,而在大型阵列上则是中速的$.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的结果是否始终存在搜索对象始终存在的小型阵列
答案 12 :(得分:10)
虽然这里有许多正确的答案,但其中许多都没有解决这样一个事实:如果不止一次这样做,这是一个不必要的昂贵操作。在极端情况下,这可能是导致实际性能问题的原因。
在现实世界中,如果您正在处理大量项目并且性能是一个问题,那么最初构建查找的速度要快得多:
create proc spGetItemsByUser
@userName nvarchar(50)
as
begin
declare @userId int
declare @feedId table (id int)
select @userId = id
from Users
where name = @userName
insert into @feedid (id)
select feedid, isread
from userstofeed
where userid = @userId
select * from feed where id in (select id from @feedId)
select isread from userstofeed where userid = @userId //Here I'm getting bit if it read or not
end
然后你可以在固定时间内获得这样的物品:
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var lookup = items.reduce((o,i)=>o[i.id]=o,{});
您也可以考虑使用Map而不是对象作为查找:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
答案 13 :(得分:10)
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
答案 14 :(得分:6)
若您多次执行此操作,您可以设置地图(ES6):
const map = new Map( myArray.map(el => [el.id, el]) );
然后你就可以做到:
map.get(27).foo
答案 15 :(得分:6)
以下是我在纯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'
答案 16 :(得分:4)
以接受的答案为基础:
jQuery的:
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)
或CoffeeScript:
foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo
答案 17 :(得分:4)
您可以从http://sugarjs.com/尝试Sugarjs。
它在阵列上有一个非常甜蜜的方法,.find
。所以你可以找到这样的元素:
array.find( {id: 75} );
您还可以向其传递具有更多属性的对象,以添加另一个“where-clause”。
请注意,Sugarjs扩展了原生对象,有些人认为这非常邪恶......
答案 18 :(得分:3)
迭代数组中的任何项目。对于您访问的每件商品,请检查该商品的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];
}
答案 19 :(得分:3)
正如其他人指出的那样,.find()
是在数组中查找一个对象时要走的路。但是,如果使用此方法找不到对象,则程序将崩溃:
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"
*/
可以通过在使用.find()
之前检查是否定义.foo
的结果来解决此问题。现代JS允许我们使用optional chaining轻松地做到这一点,如果找不到对象,则返回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
答案 20 :(得分:3)
使用Array.prototype.filter()
功能。
DEMO :https://jsfiddle.net/sumitridhal/r0cz0w5o/4/
<强> JSON 强>
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
}
}
];
过滤强>
var getPerson = function(name){
return jsonObj.filter(function(obj) {
return obj.name === name;
});
}
答案 21 :(得分:3)
即使在纯JavaScript中也可以使用内置的“过滤器”函数对数组执行此操作:
Array.prototype.filterObjects = function(key, value) {
return this.filter(function(x) { return x[key] === value; })
}
所以现在只需用“id”代替key
和“45”来代替value
,你就会得到匹配id为45的完整对象。那就是,< / p>
myArr.filterObjects("id", "45");
答案 22 :(得分:2)
只要浏览器支持ECMA-262,第5版(2009年12月),这应该可行,几乎是单行:
var bFound = myArray.some(function (obj) {
return obj.id === 45;
});
答案 23 :(得分:2)
我真的很喜欢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
&#13;
答案 24 :(得分:2)
更通用,更简短
function findFromArray(array,key,value) {
return array.filter(function (element) {
return element[key] == value;
}).shift();
}
在您的情况下var element = findFromArray(myArray,'id',45)
将为您提供整个元素。
答案 25 :(得分:1)
使用:
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {
if (obj.id === '5') { // id.toString() if it is int
retObj = obj;
return false;
}
});
return retObj;
它应该通过id返回一个对象。
答案 26 :(得分:1)
此解决方案也可能有用:
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");
我就像$.grep
一样,如果找到一个对象, function 将返回对象,而不是数组。
答案 27 :(得分:1)
在此解决方案中,当我们搜索某个对象时,会将其保存在缓存中。这是“始终搜索解决方案”和“为预先计算中的每个对象创建哈希图”之间的中间点。
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
答案 28 :(得分:0)
考虑&#34; axesOptions&#34;是一个对象格式为的对象数组 {:field_type =&gt; 2,:fields =&gt; [1,3,4]}
function getFieldOptions(axesOptions,choice){
var fields=[]
axesOptions.each(function(item){
if(item.field_type == choice)
fields= hashToArray(item.fields)
});
return fields;
}
答案 29 :(得分:0)
最短,
var theAnswerObj = _.findWhere(array, {id : 42});
答案 30 :(得分:0)
我们可以使用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,下划线https://underscorejs.org/#filter
答案 31 :(得分:0)
从aggaton's answer开始,这是一个实际返回所需元素的函数(如果未找到,则返回null
),给定array
和callback
函数返回正确的&#34;正确的&#34;元素:
function findElement(array, callback) {
var elem;
return array.some(function(e) {
if (callback(e)) {
elem = e;
return true;
}
}) ? elem : null;
});
请记住,这并不适用于IE8-,因为它不支持some
。可以提供polyfill,或者总是经典的for
循环:
function findElement(array, callback) {
for (var i = 0; i < array.length; i++)
if (callback(array[i])) return array[i];
return null;
});
它实际上更快,更紧凑。但如果你不想重新发明轮子,我建议使用像下划线或lodash这样的实用程序库。
答案 32 :(得分:-1)
最近,我不得不面对同样的事情,我需要从一个巨大的数组中搜索字符串。
经过一番搜索,我发现使用简单的代码即可轻松处理
代码:
$item['images']->file_name ?? 'default_value';
答案 33 :(得分:-3)
我找到数组索引的方法:
function getItemId(item) {
return item.id;
}
var index = myArray.map(getItemId).indexOf(id);
var item = myArray[index];
//If you want to use ES6
index = myArray.map((i) => i.id).indexOf(id);
item = myArray[index];
答案 34 :(得分:-5)
使用jQuery的过滤方法:
$(myArray).filter(function()
{
return this.id == desiredId;
}).first();
这将返回具有指定Id的第一个元素。
它还具有良好的C#LINQ外观格式。