Find value in javascript array of objects deeply nested with ES6

后端 未结 4 2067
星月不相逢
星月不相逢 2021-01-12 10:46

In an array of objects I need to find a value -- where key is activity : However the activity key can be dee

相关标签:
4条回答
  • 2021-01-12 11:14

    While not as elegant as a recursive algorithm, you could JSON.stringify() the array, which gives this:

    [{"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

    0 讨论(0)
  • 2021-01-12 11:18

    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' }
    
    0 讨论(0)
  • 2021-01-12 11:34

    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.

    var result = !!activityItems.find(function fn(item) {
      return item.activity === "Gym" || (item.items && item.items.find(fn));
    });
    
    0 讨论(0)
  • 2021-01-12 11:35

    You can use some() method and recursion to find if activity exists on any level and return true/false as result.

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

    0 讨论(0)
提交回复
热议问题