thu*_*gsb 1435 javascript arrays jquery object javascript-objects
我有一个数组:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]
Run Code Online (Sandbox Code Playgroud)
我无法改变数组的结构.我正在传递id 45
,我想'bar'
在数组中获取该对象.
如何在JavaScript或使用jQuery中执行此操作?
Guf*_*ffa 1453
由于您已经在使用jQuery,因此可以使用用于搜索数组的grep函数:
var result = $.grep(myArray, function(e){ return e.id == id; });
Run Code Online (Sandbox Code Playgroud)
结果是一个包含找到的项目的数组.如果您知道对象始终存在并且只出现一次,您可以使用它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
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ski 957
使用find()
方法:
myArray.find(x => x.id === '45').foo;
Run Code Online (Sandbox Code Playgroud)
来自MDN:
find()
如果数组中的元素满足提供的测试函数,则该方法返回数组中的值.否则undefined
返回.
如果要查找其索引,请使用findIndex()
:
myArray.findIndex(x => x.id === '45');
Run Code Online (Sandbox Code Playgroud)
来自MDN:
该
findIndex()
方法返回数组中第一个满足提供的测试函数的元素的索引.否则返回-1.
如果要获取匹配元素的数组,请改用该filter()
方法:
myArray.filter(x => x.id === '45');
Run Code Online (Sandbox Code Playgroud)
这将返回一个对象数组.如果要获取一组foo
属性,可以使用以下map()
方法执行此操作:
myArray.filter(x => x.id === '45').map(x => x.foo);
Run Code Online (Sandbox Code Playgroud)
附注:类似的方法find()
或filter()
和箭头的功能不被旧的浏览器(如IE)的支持,所以如果你想支持这些浏览器,你应该使用transpile代码巴贝尔(用填充工具).
Aar*_*lla 356
另一种解决方案是创建查找对象:
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
lookup[array[i].id] = array[i];
}
... now you can use lookup[id]...
Run Code Online (Sandbox Code Playgroud)
如果您需要进行多次查找,这一点尤其有趣.
这将不需要更多的内存,因为ID和对象将被共享.
Rún*_*erg 168
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);
Run Code Online (Sandbox Code Playgroud)
它没有外部库.但是,如果您需要较旧的浏览器支持,则可能需要包含此polyfill.
Gij*_*anB 140
Underscore.js有一个不错的方法:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
Run Code Online (Sandbox Code Playgroud)
pim*_*vdb 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
Run Code Online (Sandbox Code Playgroud)
Jar*_*Par 67
请尝试以下方法
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;
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*sso 43
myArray.filter(function(a){ return a.id == some_id_you_want })[0]
Run Code Online (Sandbox Code Playgroud)
wil*_*ell 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');
Run Code Online (Sandbox Code Playgroud)
Kam*_*ski 24
今天 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) 的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));
Run Code Online (Sandbox Code Playgroud)
<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
Run Code Online (Sandbox Code Playgroud)
Chrome 的示例测试结果,用于搜索对象始终存在的小数组
hun*_*ter 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";
Run Code Online (Sandbox Code Playgroud)
工作示例:http://jsfiddle.net/hunter/Pxaua/
Joe*_*wis 13
你可以使用过滤器,
function getById(id, myArray) {
return myArray.filter(function(obj) {
if(obj.id == id) {
return obj
}
})[0]
}
get_my_obj = getById(73, myArray);
Run Code Online (Sandbox Code Playgroud)
Tom*_*Tom 11
虽然这里有许多正确的答案,但其中许多并没有解决这样一个事实:如果不止一次这样做,这是一个不必要的昂贵操作.在极端情况下,这可能是真正的性能问题的原因.
在现实世界中,如果您正在处理大量项目并且性能是一个问题,那么最初构建查找要快得多:
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var lookup = items.reduce((o,i)=>o[i.id]=o,{});
Run Code Online (Sandbox Code Playgroud)
然后,您可以在固定时间内获取物品,如下所示:
var bar = o[id];
Run Code Online (Sandbox Code Playgroud)
您还可以考虑使用Map而不是对象作为查找:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
lag*_*lex 10
Array.reduce
var array = [ {'id':'73' ,'foo':'bar'} , {'id':'45' ,'foo':'bar'} , ];
var id = 73;
Run Code Online (Sandbox Code Playgroud)
var found = array.reduce(function(a, b){
return (a.id==id && a) || (b.id == id && b)
});
Run Code Online (Sandbox Code Playgroud)
如果找到则返回object元素,否则返回 false
最近,我不得不面对同样的事情,我需要从一个巨大的数组中搜索字符串。
经过一番搜索,我发现用简单的代码很容易处理:
代码:
var items = mydata.filter(function(item){
return item.word.toLowerCase().startsWith( 'gk );
})
Run Code Online (Sandbox Code Playgroud)
见https://jsfiddle.net/maheshwaghmare/cfx3p40v/4/
只要浏览器支持ECMA-262,第 5 版(2009 年 12 月),这应该可以工作,几乎是单行的:
var bFound = myArray.some(function (obj) {
return obj.id === 45;
});
Run Code Online (Sandbox Code Playgroud)
迭代数组中的任何项目。对于您访问的每个项目,请检查该项目的 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
}
Run Code Online (Sandbox Code Playgroud)
同样的事情使用 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];
}
Run Code Online (Sandbox Code Playgroud)
您可以从http://sugarjs.com/尝试 Sugarjs 。
它在数组上有一个非常好的方法,.find
. 所以你可以找到这样的元素:
array.find( {id: 75} );
Run Code Online (Sandbox Code Playgroud)
您还可以将具有更多属性的对象传递给它以添加另一个“where-clause”。
请注意,Sugarjs 扩展了原生对象,有些人认为这非常邪恶......
以下是我在纯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'
Run Code Online (Sandbox Code Playgroud)
如果您多次执行此操作,则可以设置地图(ES6):
const map = new Map( myArray.map(el => [el.id, el]) );
Run Code Online (Sandbox Code Playgroud)
然后,您可以简单地执行以下操作:
map.get(27).foo
Run Code Online (Sandbox Code Playgroud)
小智 6
我们可以使用 Jquery 方法 $.each()/$.grep()
var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}
Run Code Online (Sandbox Code Playgroud)
或者
var data = $.grep(array, function( n, i ) {
return ( n !== 5 && i > 4 );
});
Run Code Online (Sandbox Code Playgroud)
使用 ES6 语法:
Array.find, Array.filter, Array.forEach, Array.map
Run Code Online (Sandbox Code Playgroud)
或者使用 Lodash https://lodash.com/docs/4.17.10#filter,下划线https://underscorejs.org/#filter
正如其他人指出的那样,.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"
*/
Run Code Online (Sandbox Code Playgroud)
这可以通过.find()
在使用 using 之前检查结果是否已定义来.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
Run Code Online (Sandbox Code Playgroud)
基于公认的答案:
jQuery:
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)
Run Code Online (Sandbox Code Playgroud)
或 CoffeeScript:
foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo
Run Code Online (Sandbox Code Playgroud)
使用Array.prototype.filter()
功能。
演示:https : //jsfiddle.net/sumiridhal/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
}
}
];
Run Code Online (Sandbox Code Playgroud)
筛选
var getPerson = function(name){
return jsonObj.filter(function(obj) {
return obj.name === name;
});
}
Run Code Online (Sandbox Code Playgroud)
小智 5
更通用,更简短
function findFromArray(array,key,value) {
return array.filter(function (element) {
return element[key] == value;
}).shift();
}
Run Code Online (Sandbox Code Playgroud)
在您的情况下 var element = findFromArray(myArray,'id',45)
这将为您提供整个元素。
归档时间: |
|
查看次数: |
1313503 次 |
最近记录: |