In an array of objects I need to find a value
-- where key
is activity
: However the activity
key
can be deeply nested in the array like so:
在一个对象数组中,我需要找到一个值 - 其中key是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',
},
],
},
],
},
{} ...
{} ...
];
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 ES6
way 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
谢谢
3 个解决方案
#1
3
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'))
#2
1
First, your function could be improved by halting once a match is found via the recursive call. Also, you're both declaring match
outside, as well as returning it. Probably better to just return.
首先,通过递归调用找到匹配后暂停,可以改善您的功能。此外,你既要在外面宣布比赛,也要归还。回来可能更好。
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 .find
with a named function if you wish.
没有内置的深度搜索,但如果您愿意,可以将.find与命名函数一起使用。
var result = !!activityItems.find(function fn(item) {
return item.activity === "Gym" || (item.items && item.items.find(fn));
});
#3
0
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 literal to 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
#1
3
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'))
#2
1
First, your function could be improved by halting once a match is found via the recursive call. Also, you're both declaring match
outside, as well as returning it. Probably better to just return.
首先,通过递归调用找到匹配后暂停,可以改善您的功能。此外,你既要在外面宣布比赛,也要归还。回来可能更好。
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 .find
with a named function if you wish.
没有内置的深度搜索,但如果您愿意,可以将.find与命名函数一起使用。
var result = !!activityItems.find(function fn(item) {
return item.activity === "Gym" || (item.items && item.items.find(fn));
});
#3
0
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 literal to 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