Search code examples
jsonfilterecmascript-5

ES5 javascript Filter JSON object based on array multiple key object


With Javascript ES5, return JSON object based on tags array. Each object have tags array and I am trying to return only the object that matches all of the tags.name.

For example, if the filter condition based on all tags name (tags[0].name , tags[1].name , tags[2].name ) is ['energy', 'video'], the return object should have tags name containing both energy and video (it can still have other tags like featured)

tags: [
        {
          localizedTitle: null,
          title: 'Featured',
          name: 'featured'
        },
        {
          localizedTitle: null,
          title: 'Video',
          name: 'video'
        },
        {
          localizedTitle: null,
          title: 'Energy',
          name: 'energy'
        }
      ]

Using Array.prototype.filter(), I was able to return object that match single value -> tags[0].name However, I need to return object based on all the tags name -> tags[0].name , tags[1].name , tags[2].name

I tried using Array.prototype.map() to combine all tags name to an array -> Array(3) [ "featured", "video", "energy" ]

And tried with Array.prototype.filter() to return object based on the new tag array but it doesn't return any object but Array []

Kindly see testing code at https://codepen.io/anon/pen/KjLKBR

I expect the output return object of

{
      title: 'Video Energy Featured',
      tags: [
        {
          localizedTitle: null,
          title: 'Featured',
          name: 'featured'
        },
        {
          localizedTitle: null,
          title: 'Video',
          name: 'video'
        },
        {
          localizedTitle: null,
          title: 'Energy',
          name: 'energy'
        }
      ]
    }

Thanks a lot in advance. Much appreciated.


Solution

  • You were on the right track using filter. Here is my take on your problem.

    function filterItems(items, tags) {
      return items.filter(function(item) {
        var itemTags = item.tags.map(function (tag) { return tag.name; });
        return tags.every(function(tag) { return itemTags.indexOf(tag) > -1  });
      })
    }
    

    You call it with the items to filter and the list of tags. It returns the filtered list.

    It is not the most optimal code, but it should do the work.