在与 ES6 深度嵌套的对象的 javascript 数组中查找值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46329392/
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
Find value in javascript array of objects deeply nested with ES6
提问by user2456977
In an array of objects I need to find a value-- where keyis activity: However the activitykeycan be deeply nested in the array like so:
在一个对象数组中,我需要找到一个value-- where keyis activity:但是activitykey可以像这样深入嵌套在数组中:
const activityItems = [
{
name: 'Sunday',
items: [
{
name: 'Gym',
activity: 'weights',
},
],
},
{
name: 'Monday',
items: [
{
name: 'Track',
activity: 'race',
},
{
name: 'Work',
activity: 'meeting',
},
{
name: 'Swim',
items: [
{
name: 'Beach',
activity: 'scuba diving',
},
{
name: 'Pool',
activity: 'back stroke',
},
],
},
],
},
{} ...
{} ...
];
So I wrote a recursive algorithm to find out if a certain activity is in the array:
所以我写了一个递归算法来找出某个活动是否在数组中:
let match = false;
const findMatchRecursion = (activity, activityItems) => {
for (let i = 0; i < activityItems.length; i += 1) {
if (activityItems[i].activity === activity) {
match = true;
break;
}
if (activityItems[i].items) {
findMatchRecursion(activity, activityItems[i].items);
}
}
return match;
};
Is there an ES6way of determining if an activity exists in an array like this?
有没有ES6办法确定活动是否存在于这样的数组中?
I tried something like this:
我试过这样的事情:
const findMatch(activity, activityItems) {
let obj = activityItems.find(o => o.items.activity === activity);
return obj;
}
But this won't work with deeply nested activities.
但这不适用于深度嵌套的活动。
Thanks
谢谢
采纳答案by Nenad Vracar
You can use some()method and recursion to find if activity exists on any level and return true/false as result.
您可以使用some()方法和递归来查找活动是否存在于任何级别并返回 true/false 作为结果。
const activityItems = [{"name":"Sunday","items":[{"name":"Gym","activity":"weights"}]},{"name":"Monday","items":[{"name":"Track","activity":"race"},{"name":"Work","activity":"meeting"},{"name":"Swim","items":[{"name":"Beach","activity":"scuba diving"},{"name":"Pool","activity":"back stroke"}]}]}]
let findDeep = function(data, activity) {
return data.some(function(e) {
if(e.activity == activity) return true;
else if(e.items) return findDeep(e.items, activity)
})
}
console.log(findDeep(activityItems, 'scuba diving'))
回答by Rick Hitchcock
While not as elegant as a recursive algorithm, you could JSON.stringify()the array, which gives this:
虽然不像递归算法那么优雅,但你可以JSON.stringify()数组,它给出了这个:
[{"name":"Sunday","items":[{"name":"Gym","activity":"weights"}]},{"name":"Monday","items":[{"name":"Track","activity":"race"},{"name":"Work","activity":"meeting"},{"name":"Swim","items":[{"name":"Beach","activity":"scuba diving"},{"name":"Pool","activity":"back stroke"}]}]}]
You could then use a template literalto search for the pattern:
然后,您可以使用模板文字来搜索模式:
`"activity":"${activity}"`
Complete function:
功能齐全:
findMatch = (activity, activityItems) =>
JSON.stringify(activityItems).includes(`"activity":"${activity}"`);
const activityItems = [{
name: 'Sunday',
items: [{
name: 'Gym',
activity: 'weights',
}, ],
},
{
name: 'Monday',
items: [{
name: 'Track',
activity: 'race',
},
{
name: 'Work',
activity: 'meeting',
},
{
name: 'Swim',
items: [{
name: 'Beach',
activity: 'scuba diving',
},
{
name: 'Pool',
activity: 'back stroke',
},
],
},
],
}
];
findMatch = (activity, activityItems) =>
JSON.stringify(activityItems).includes(`"activity":"${activity}"`);
console.log(findMatch('scuba diving', activityItems)); //true
console.log(findMatch('dumpster diving', activityItems)); //false
回答by llama
First, your function could be improved by halting once a match is found via the recursive call. Also, you're both declaring matchoutside, as well as returning it. Probably better to just return.
首先,一旦通过递归调用找到匹配项,就可以通过暂停来改进您的功能。此外,你们既在match外面声明,又在返回它。可能更好地返回。
const findMatchRecursion = (activity, activityItems) => {
for (let i = 0; i < activityItems.length; i += 1) {
if (activityItems[i].activity === activity) {
return true;
}
if (activityItems[i].items && findMatchRecursion(activity, activityItems[i].items) {
return true;
}
}
return false;
};
There's no built in deep search, but you can use .findwith a named function if you wish.
没有内置的深度搜索,但.find如果您愿意,可以使用命名函数。
var result = !!activityItems.find(function fn(item) {
return item.activity === "Gym" || (item.items && item.items.find(fn));
});

