如何在 JavaScript 中的对象数组中查找值?
Posted
技术标签:
【中文标题】如何在 JavaScript 中的对象数组中查找值?【英文标题】:How to find a value in an array of objects in JavaScript? 【发布时间】:2011-07-08 01:53:42 【问题描述】:我有一个对象数组:
Object =
1 : name : bob , dinner : pizza ,
2 : name : john , dinner : sushi ,
3 : name : larry, dinner : hummus
我希望能够在对象/数组中搜索键为“dinner”的位置,并查看它是否与“sushi”匹配。
我知道 jQuery 有 $.inArray,但它似乎不适用于对象数组。或者也许我错了。 indexOf 似乎也只适用于一个数组级别。
是否没有此功能或现有代码?
【问题讨论】:
这已经被问过了。您必须编写自己的函数或使用其他库。 请注意Object
在javascript中是保留的,Object
是object对象,即所有对象之母。
问题和接受的答案与多维数组无关,而更多地与通过其项目的属性值过滤的一维数组有关。 => 他们没有解决我的问题“在多维数组中查找值”。
【参考方案1】:
如果你有一个数组比如
var people = [
"name": "bob", "dinner": "pizza" ,
"name": "john", "dinner": "sushi" ,
"name": "larry", "dinner": "hummus"
];
您可以使用数组对象的filter
方法:
people.filter(function (person) return person.dinner == "sushi" );
// => [ "name": "john", "dinner": "sushi" ]
在较新的 JavaScript 实现中,您可以使用函数表达式:
people.filter(p => p.dinner == "sushi")
// => [ "name": "john", "dinner": "sushi" ]
您可以使用map
搜索拥有"dinner": "sushi"
的人
people.map(function (person)
if (person.dinner == "sushi")
return person
else
return null
); // => [null, "name": "john", "dinner": "sushi" , null]
或reduce
people.reduce(function (sushiPeople, person)
if (person.dinner == "sushi")
return sushiPeople.concat(person);
else
return sushiPeople
, []); // => [ "name": "john", "dinner": "sushi" ]
我相信您可以将其推广到任意键和值!
【讨论】:
请记住,这些解决方案是 ECMAScript 5 的一部分,在 IE8 中不受支持。 kangax.github.com/es5-compat-table 尽管我更喜欢 @adamse 的回答,但亚历克斯的回答对“旧的垃圾浏览器”更友好。但不确定性能。 @SalmanA - 问题或解决方案都不是指 jQuery。使用了 javascript filter(),而不是 jQuery 特定的 $.filter() - tutorialspoint.com/javascript/array_filter.htm 如EasyCo所说,IE8不支持过滤功能。但是,它很容易添加到 Array 原型中,因此可以在脚本开头带有小功能的任何浏览器中使用。这在filter documentation 中有概述。它给出了 ECMA-262 中指定的确切功能,所以实际上是一样的。 我刚刚添加了an answer,它使用了jQuery的grep
方法。将您的答案作为与您正在做的事情相同的概念可能是有意义的,但是依赖于 jQuery 并且对浏览器友好。
我的返回变量是否不断出现引用错误?我尝试了返回“x”的前两个答案,它一直说它是未定义的......【参考方案2】:
jQuery 有一个内置方法 jQuery.grep
,其工作方式类似于来自 @adamse's Answer 的 ES5 filter
函数,并且应该在旧版浏览器上运行良好。
以亚当斯为例:
var peoples = [
"name": "bob", "dinner": "pizza" ,
"name": "john", "dinner": "sushi" ,
"name": "larry", "dinner": "hummus"
];
您可以执行以下操作
jQuery.grep(peoples, function (person) return person.dinner == "sushi" );
// => [ "name": "john", "dinner": "sushi" ]
【讨论】:
【参考方案3】:var getKeyByDinner = function(obj, dinner)
var returnKey = -1;
$.each(obj, function(key, info)
if (info.dinner == dinner)
returnKey = key;
return false;
;
);
return returnKey;
jsFiddle.
只要-1
永远不是有效的密钥。
【讨论】:
差一点点赞了这个,但帖子里没有解释。【参考方案4】:如果您要经常进行此搜索,请考虑更改对象的格式,以便晚餐实际上是关键。这有点像在数据库表中分配主聚集键。所以,例如:
Obj = 'pizza' : 'name' : 'bob' , 'sushi' : 'name' : 'john'
您现在可以像这样轻松访问它:Object['sushi']['name']
或者如果对象真的这么简单(只是对象中的“名称”),您可以将其更改为:
Obj = 'pizza' : 'bob', 'sushi' : 'john'
然后像这样访问它:Object['sushi']
。
显然,像这样重构数据对象并不总是可能或对您有利,但关键是,有时最好的答案是考虑您的数据对象是否以最佳方式构建。像这样创建密钥可以更快并创建更简洁的代码。
【讨论】:
爱你回答,但我发现语法有问题:我的工作方式是这样的:obj = "pizza" : "name" : "bob" , "sushi" : "name" : "约翰" 警报 (obj['pizza']['name']);但仍然。谢谢!找到了我正在寻找的东西! ) @alexela 感谢 alexela!我用你的敏锐观察更新了我的答案!我刚刚复制了 OP 帖子中的示例并忽略了添加引号,但你是对的 - 除非至少在值周围有引号(假设它们是值而不是变量),否则它将不起作用。【参考方案5】:您可以使用Alasql library 在数组中找到对象:
var data = [ name : "bob" , dinner : "pizza" , name : "john" , dinner : "sushi" ,
name : "larry", dinner : "hummus" ];
var res = alasql('SELECT * FROM ? WHERE dinner="sushi"',[data]);
试试这个例子in jsFiddle。
【讨论】:
我不确定这是否真的应该被否决。当需求变得比单个过滤器或减少调用更复杂时,对集合的类似 Sql 的查询变得更容易推理和编写。 Alasql 是一个非常令人印象深刻的库,但对于上面的示例来说确实有点矫枉过正。 如果对象本身来自 SQL 源,那么这个答案简直是天才。【参考方案6】:您可以使用简单的 for in 循环:
for (prop in Obj)
if (Obj[prop]['dinner'] === 'sushi')
// Do stuff with found object. E.g. put it into an array:
arrFoo.push(Obj[prop]);
以下小提琴示例将所有包含dinner:sushi
的对象放入一个数组中:
https://jsfiddle.net/3asvkLn6/1/
【讨论】:
【参考方案7】:这里已经有很多很好的答案了,为什么不多一个,使用像 lodash 或 underscore 之类的库:)
obj =
1 : name : 'bob' , dinner : 'pizza' ,
2 : name : 'john' , dinner : 'sushi' ,
3 : name : 'larry', dinner : 'hummus'
_.where(obj, dinner: 'pizza')
>> ["name":"bob","dinner":"pizza"]
【讨论】:
【参考方案8】:我必须在嵌套站点地图结构中搜索与给定路径匹配的第一个叶项。我使用.map()
.filter()
和.reduce
想出了以下代码。返回找到的与路径 /c
匹配的最后一项。
var sitemap =
nodes: [
items: [ path: "/a" , path: "/b" ]
,
items: [ path: "/c" , path: "/d" ]
,
items: [ path: "/c" , path: "/d" ]
]
;
const item = sitemap.nodes
.map(n => n.items.filter(i => i.path === "/c"))
.reduce((last, now) => last.concat(now))
.reduce((last, now) => now);
【讨论】:
【参考方案9】:如果您想通过搜索功能查找特定对象,请尝试以下操作:
function findArray(value)
let countLayer = dataLayer.length;
for(var x = 0 ; x < countLayer ; x++)
if(dataLayer[x].user)
let newArr = dataLayer[x].user;
let data = newArr[value];
return data;
return null;
findArray("id");
这是一个示例对象:
layerObj =
0: gtm.start :1232542, event: "gtm.js",
1: event: "gtm.dom", gtm.uniqueEventId: 52,
2: visitor id: "abcdef2345",
3: user: id: "29857239", verified: "Null", user_profile: "Personal", billing_subscription: "True", partners_user: "adobe"
代码将迭代并找到“用户”数组,并搜索您在其中寻找的对象。
我的问题是数组索引在每次窗口刷新时都会更改,并且它在第三个或第二个数组中,但这并不重要。
对我来说就像一个魅力!
在你的例子中它有点短:
function findArray(value)
let countLayer = Object.length;
for(var x = 0 ; x < countLayer ; x++)
if(Object[x].dinner === value)
return Object[x];
return null;
findArray('sushi');
【讨论】:
【参考方案10】:我们使用object-scan 进行大部分数据处理。它在概念上非常简单,但允许很多很酷的东西。以下是您解决问题的方法
// const objectScan = require('object-scan');
const findDinner = (dinner, data) => objectScan(['*'],
abort: true,
rtn: 'value',
filterFn: ( value ) => value.dinner === dinner
)(data);
const data = 1: name: 'bob', dinner: 'pizza' , 2: name: 'john', dinner: 'sushi' , 3: name: 'larry', dinner: 'hummus' ;
console.log(findDinner('sushi', data));
// => name: 'john', dinner: 'sushi'
.as-console-wrapper max-height: 100% !important; top: 0
<script src="https://bundle.run/object-scan@13.8.0"></script>
免责声明:我是object-scan的作者
【讨论】:
以上是关于如何在 JavaScript 中的对象数组中查找值?的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript:查找值是不是在数组中的对象内的最佳方法[重复]