javascript - Filter JS multidimensional array - Stack Overflow

admin2025-04-17  1

I am attempting to filter some events and their corresponding time slots. The data structure is like so:

var items = [
  {
    title: 'Category Title',
    events: [
      {
        title : '1:00pm',
        category : 1
      },
      {
        title: '2:00pm',
        category : 2
      }
    ]
  },
  {
    title: 'Category Title 2',
    events: [
      {
        title : '3:00pm',
        category : 1
      },
      {
        title: '4:00pm',
        category : 2
      }
    ]
  }
];

I am wanting to filter events by their category. I've tried using filters/maps but can't seem to figure it out. For example, how would I filter the list to only return items with the category of 1?

I am attempting to filter some events and their corresponding time slots. The data structure is like so:

var items = [
  {
    title: 'Category Title',
    events: [
      {
        title : '1:00pm',
        category : 1
      },
      {
        title: '2:00pm',
        category : 2
      }
    ]
  },
  {
    title: 'Category Title 2',
    events: [
      {
        title : '3:00pm',
        category : 1
      },
      {
        title: '4:00pm',
        category : 2
      }
    ]
  }
];

I am wanting to filter events by their category. I've tried using filters/maps but can't seem to figure it out. For example, how would I filter the list to only return items with the category of 1?

Share edited Apr 10, 2018 at 22:29 acdcjunior 136k37 gold badges338 silver badges310 bronze badges asked Apr 10, 2018 at 21:42 Grant VinsonGrant Vinson 2171 gold badge5 silver badges14 bronze badges 6
  • Use Array.prototype.some() to search for a matching category. – Barmar Commented Apr 10, 2018 at 21:44
  • There are also useful functions in underscore.js and lodash. – Barmar Commented Apr 10, 2018 at 21:45
  • 1 Do you want to filter the array events or the parent array items which array events contain category === 1? – Ele Commented Apr 10, 2018 at 21:53
  • @Ele I am trying to return all of the events and their parent title where the individual event categories === 1. – Grant Vinson Commented Apr 10, 2018 at 21:55
  • 1 Can you post the desired output? – Ele Commented Apr 10, 2018 at 22:01
 |  Show 1 more ment

5 Answers 5

Reset to default 2

You can use the function filter along with the function some to get those items with a specific category within the array events.

This example has an item which events array contains a category === 3

var items = [  {    title: 'Category Title',    events: [      {        title : '1:00pm',        category : 1      },      {        title: '2:00pm',        category : 2      }    ]  },  {    title: 'Category Title 2',    events: [      {        title : '3:00pm',        category : 1      },      {        title: '4:00pm',        category : 2      }    ]  },  {    title: 'Category Title 3',    events: [      {        title : '3:00pm',        category : 1      },      {        title: '4:00pm',        category : 3      }    ]  }],
    cat = 3,
    result = items.filter(o => o.events.some(({category}) => cat === category));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

If you need to get only the events with category === 3 use the function reduce:

var items = [  {    title: 'Category Title',    events: [      {        title : '1:00pm',        category : 1      },      {        title: '2:00pm',        category : 2      }    ]  },  {    title: 'Category Title 2',    events: [      {        title : '3:00pm',        category : 1      },      {        title: '4:00pm',        category : 2      }    ]  },  {    title: 'Category Title 3',    events: [      {        title : '3:00pm',        category : 1      },      {        title: '4:00pm',        category : 3      }    ]  }],
    cat = 3,
    result = items.reduce((a/*Accumulator*/, o/*Current object in array*/) => { 
      // 1. We get the events with a specific category  (In this case -> 3)
      var filtered = o.events.filter(({category}) => cat === category);
      
      // 2. If the previous filter returns at least one event, we need to push
      //    the current object 'o' with the filtered events.
      if (filtered.length) { // if length !== 0 we need to push the object.
        // 3. We use Object.assign to avoid any mutation over the original object.
        //    So, basically we create a new object with the original properties
        //    and finally we assign the filtered events to the property events.
        a.push(Object.assign({}, o, {events: filtered}));
      }
      
      return a;
    }, []/*Initial value (this array will contain the filtered objects)*/);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

What you should do here is to use Array.filter() method to filter your items array, based on the sub events array, which you can test upon with Array.some() to find those with category===1.

var filteredResults = items.filter(function(item) {
  return item.events.some(e => e.category === 1);
});

Demo:

var items = [{
    title: 'Category Title',
    events: [{
        title: '1:00pm',
        category: 1
      },
      {
        title: '2:00pm',
        category: 2
      }
    ]
  },
  {
    title: 'Category Title 2',
    events: [{
        title: '3:00pm',
        category: 1
      },
      {
        title: '4:00pm',
        category: 2
      }
    ]
  }
];

var result = items.filter(function(item) {
  return item.events.some(e => e.category === 1);
});


console.log(result);

you can use filter to get the reduced list but you can do this in other ways like reduce.

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

var items = [
  {
    title: 'Category Title',
    events: [
      {
        title : '1:00pm',
        category : 1
      },
      {
        title: '2:00pm',
        category : 2
      }
    ]
  },
  {
    title: 'Category Title 2',
    events: [
      {
        title : '3:00pm',
        category : 1
      },
      {
        title: '4:00pm',
        category : 2
      }
    ]
  }
];
let cat1, cat2;
items.forEach(item => {
  cat1 = item.events.filter(item => item.category === 1)
  cat2 = item.events.filter(item => item.category === 2)
})


console.log(cat1, cat2)

Heres a bit more advanced you can give the function an array of categories you want and it will return an object with keys of all the categories and the events inside them. Hope this helps.

var items = [
      {
        title: 'Category Title',
        events: [
          {
            title : '1:00pm',
            category : 1
          },
          {
            title: '2:00pm',
            category : 2
          }
        ]
      },
      {
        title: 'Category Title 2',
        events: [
          {
            title : '3:00pm',
            category : 1
          },
          {
            title: '4:00pm',
            category : 2
          }
        ]
      }
    ];
    
    function filter(cat, arr) {
      return arr.filter(i => i.category === cat);
    }
    function getCategorys(category) {
      return items.reduce((prev, curr) => {
         category.forEach(cat => {
         !prev[cat] ? prev[cat] = [] : null;
         prev[cat] = [...filter(cat, curr.events), ...prev[cat]];
         })
         return prev;
      }, {})
    }
    
    console.log(getCategorys([1,2]))

You can use the following functions to get desired result:

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

function filterByCategory(items, category) {
    return items.reduce((events, i) => {
        const filteredEvents = i.events.filter(e => e.category === category);
        if (filteredEvents) {
            return events.concat(filteredEvents);
        }
        return events;
    }, []);
}
function hasCategory(item, cat) {
    for(e in item.events){
    if(item.events[e].category === cat) {
       return true;
     break;
    }
   }
   return false;
}

var filtered = items.filter((item) => {
    return hasCategory(item, 2);
});

console.log(filtered);
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744857021a270888.html

最新回复(0)