在与 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 06:35:53  来源:igfitidea点击:

Find value in javascript array of objects deeply nested with ES6

javascriptarraysalgorithmes6-modules

提问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));
});