如何在 Javascript 中的多维对象/数组中查找值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5181493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find a value in a multidimensional object/array in Javascript?
提问by Questioner
I have a multidimensional object (it's basically an array):
我有一个多维对象(它基本上是一个数组):
Object = {
1 : { name : bob , dinner : pizza },
2 : { name : john , dinner : sushi },
3 : { name : larry, dinner : hummus }
}
I want to be able to search the object/array for where the key is "dinner", and see if it matches "sushi".
我希望能够在对象/数组中搜索键为“dinner”的位置,并查看它是否与“sushi”匹配。
I know jQuery has $.inArray, but it doesn't seem to work on multidimensional arrays. Or maybe I'm wrong. indexOf also seems to only work on one array level.
我知道 jQuery 有 $.inArray,但它似乎不适用于多维数组。或者也许我错了。indexOf 似乎也只适用于一个数组级别。
Is there no function or existing code for this?
有没有这方面的功能或现有代码?
回答by adamse
If you have an array such as
如果您有一个数组,例如
var people = [
{ "name": "bob", "dinner": "pizza" },
{ "name": "john", "dinner": "sushi" },
{ "name": "larry", "dinner": "hummus" }
];
You can use the filter
method of an Array object:
您可以使用filter
Array 对象的方法:
people.filter(function (person) { return person.dinner == "sushi" });
// => [{ "name": "john", "dinner": "sushi" }]
In newer JavaScript implementations you can use a function expression:
在较新的 JavaScript 实现中,您可以使用函数表达式:
people.filter(p => p.dinner == "sushi")
// => [{ "name": "john", "dinner": "sushi" }]
You can search for people who have "dinner": "sushi"
using a map
您可以搜索"dinner": "sushi"
使用map
people.map(function (person) {
if (person.dinner == "sushi") {
return person
} else {
return null
}
}); // => [null, { "name": "john", "dinner": "sushi" }, null]
or a reduce
或 reduce
people.reduce(function (sushiPeople, person) {
if (person.dinner == "sushi") {
return sushiPeople.concat(person);
} else {
return sushiPeople
}
}, []); // => [{ "name": "john", "dinner": "sushi" }]
I'm sure you are able to generalize this to arbitrary keys and values!
我相信您可以将其推广到任意键和值!
回答by Zach Lysobey
jQuery has a built-in method jQuery.grep
that works similarly to the ES5 filter
function from @adamse's Answerand should work fine on older browsers.
jQuery 有一个内置方法jQuery.grep
,其工作方式类似于@adamse's Answer 中的 ES5filter
函数,并且应该可以在较旧的浏览器上正常工作。
Using adamse's example:
使用亚当斯的例子:
var peoples = [
{ "name": "bob", "dinner": "pizza" },
{ "name": "john", "dinner": "sushi" },
{ "name": "larry", "dinner": "hummus" }
];
you can do the following
您可以执行以下操作
jQuery.grep(peoples, function (person) { return person.dinner == "sushi" });
// => [{ "name": "john", "dinner": "sushi" }]
回答by alex
回答by dallin
If you're going to be doing this search frequently, consider changing the format of your object so dinner actually is a key. This is kind of like assigning a primary clustered key in a database table. So, for example:
如果您要经常进行此搜索,请考虑更改对象的格式,以便晚餐实际上是一个关键。这有点像在数据库表中分配主聚集键。因此,例如:
Obj = { 'pizza' : { 'name' : 'bob' }, 'sushi' : { 'name' : 'john' } }
You can now easily access it like this: Object['sushi']['name']
您现在可以像这样轻松访问它: Object['sushi']['name']
Or if the object really is this simple (just 'name' in the object), you could just change it to:
或者,如果对象确实如此简单(对象中只是“名称”),您可以将其更改为:
Obj = { 'pizza' : 'bob', 'sushi' : 'john' }
And then access it like: Object['sushi']
.
然后像这样访问它:Object['sushi']
。
It's obviously not always possible or to your advantage to restructure your data object like this, but the point is, sometimes the best answer is to consider whether your data object is structured the best way. Creating a key like this can be faster and create cleaner code.
显然,像这样重构数据对象并不总是可行或对您有利,但重点是,有时最好的答案是考虑您的数据对象是否以最佳方式构建。创建这样的密钥可以更快并创建更清晰的代码。
回答by agershun
You can find the object in array with Alasqllibrary:
您可以使用Alasql库在数组中找到对象:
var data = [ { name : "bob" , dinner : "pizza" }, { name : "john" , dinner : "sushi" },
{ name : "larry", dinner : "hummus" } ];
var res = alasql('SELECT * FROM ? WHERE dinner="sushi"',[data]);
Try this example in jsFiddle.
在 jsFiddle 中试试这个例子。
回答by Rotareti
You can use a simple for in loop:
您可以使用一个简单的 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]);
}
}
The following fiddle example puts all objects that contain dinner:sushi
into an array:
以下小提琴示例将包含的所有对象dinner:sushi
放入数组中:
回答by TomDotTom
There's already a lot of good answers here so why not one more, use a library like lodash or underscore :)
这里已经有很多很好的答案了,所以为什么不多一个,使用像 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"}]
回答by Marc
I had to search a nested sitemap structure for the first leaf item that machtes a given path. I came up with the following code just using .map()
.filter()
and .reduce
. Returns the last item found that matches the path /c
.
我必须在嵌套的站点地图结构中搜索匹配给定路径的第一个叶项。我想出了以下代码,只是使用.map()
.filter()
and .reduce
。返回找到的与 path 匹配的最后一项/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);
回答by vincent
I would try not to reinvent the wheel. We use object-scanfor all our data processing needs. It's conceptually very simple, but allows for a lot of cool stuff. Here is how you would solve your specific question
我会尽量不重新发明轮子。我们使用对象扫描来满足我们所有的数据处理需求。它在概念上非常简单,但允许很多很酷的东西。以下是您解决具体问题的方法
Data Definition
数据定义
const data = {
1 : { name : 'bob' , dinner : 'pizza' },
2 : { name : 'john' , dinner : 'sushi' },
3 : { name : 'larry', dinner : 'hummus' }
};
Logic
逻辑
const objectScan = require('object-scan');
const scanner = (input) => {
let obj = null;
objectScan(['*.dinner'], {
filterFn: (key, value, { parents }) => {
if (value === 'sushi') {
obj = parents[0];
}
},
breakFn: () => obj !== null
})(data);
return obj;
};
const result = scanner(data);
Output
输出
// => result
{
"name": "john",
"dinner": "sushi"
}
回答by z3r0
If You want to find a specific object via search function just try something like this:
如果您想通过搜索功能查找特定对象,请尝试以下操作:
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");
This is an example object:
这是一个示例对象:
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"}
}
Code will iterate and find the "user" array and will search for the object You seek inside.
代码将迭代并找到“用户”数组,并将搜索您在里面寻找的对象。
My problem was when the array index changed every window refresh and it was either in 3rd or second array, but it does not matter.
我的问题是每次窗口刷新时数组索引都会更改,并且它位于第三个或第二个数组中,但这并不重要。
Worked like a charm for Me!
对我来说就像一个魅力!
In Your example it is a bit shorter:
在你的例子中,它有点短:
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');