在与ES6

时间:2017-09-20 18:32:30

标签: javascript arrays algorithm es6-modules

在一个对象数组中,我需要找到value - 其中keyactivity:但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',
                    },
                ],
            },
        ],    
    },
    {} ...
    {} ...
];

所以我编写了一个递归算法来查明某个活动是否在数组中:

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;
};

是否有ES6方法来确定此类数组中是否存在活动?

我试过这样的事情:

const findMatch(activity, activityItems) {
    let obj = activityItems.find(o => o.items.activity === activity);
    return obj;
}

但这不适用于深层嵌套的活动。

由于

4 个答案:

答案 0 :(得分:5)

您可以使用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'))

答案 1 :(得分:3)

虽然没有递归算法那么优雅,但你可以 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"}]}]}]

然后,您可以使用template literal搜索模式:

`"activity":"${activity}"`

完成功能:

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

答案 2 :(得分:1)

首先,通过递归调用找到匹配后暂停,可以改善您的功能。此外,您既可以在外面声明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;
};

没有内置的深度搜索,但如果您愿意,可以将.find与命名函数一起使用。

var result = !!activityItems.find(function fn(item) {
  return item.activity === "Gym" || (item.items && item.items.find(fn));
});

答案 3 :(得分:0)

我们现在将object-scan用于类似这样的简单数据处理任务。一旦将头放在如何使用它的周围,那真的很好。这是一个可以回答您问题的方法

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' }