[英]Find value in javascript array of objects deeply nested with ES6
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:在对象数组中,我需要找到一个
value
——其中key
是activity
:但是activity
key
可以像这样深入嵌套在数组中:
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谢谢
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'))
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
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.此外,你们都在外面声明
match
,并返回它。 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));
});
We now use object-scan for simple data processing tasks like this.我们现在使用对象扫描来完成这样的简单数据处理任务。 It's really good once you wrap your head around how to use it.
一旦你了解如何使用它,这真的很好。 Here is how one could answer your questions
这是人们如何回答您的问题
// const objectScan = require('object-scan'); const find = (activity, input) => objectScan(['**'], { abort: true, rtn: 'value', filterFn: ({ value }) => value.activity === activity })(input); 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"}]}]}] console.log(find('scuba diving', activityItems)); // => { name: 'Beach', activity: 'scuba diving' }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>
Disclaimer : I'm the author of object-scan免责声明:我是对象扫描的作者
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.