Search code examples
javascriptarrayscountnestedduplicates

Counting Duplicates In Sub Array and assigning to property


I have an array of objects with a nested array in which I would like to count duplicate occurances and map them to a counter property.

Input Array:

initialArr = [
              {
               id: 99,
               days: [{date: '2022-08-01'},
                      {date: '2022-08-03'},
                      {date: '2022-08-03'},
                      {date: '2022-08-01'}]
              },
              {
               id: 100,
               days: [{date: '2022-08-01'},
                      {date: '2022-08-02'},
                      {date: '2022-08-02'}]
               }
              ]

Expected output array with counter property:

outputArr = [
              {
               id: 99,
               days: [{date: '2022-08-01', count: 2},
                      {date: '2022-08-03', count: 2},
                     ]
              },
              {
               id: 100,
               days: [{date: '2022-08-01', count: 1},
                      {date: '2022-08-02', count: 2},
               }
              ]

What is the best way to go about this? I have tried a couple methods using map and reduce but I'm running into difficulties with the nesting of the arrays. Any help is greatly appreciated!


Solution

  • Working inside to out, start with the days array...

    function removeDupDays(days) {
      // this produces { dateString: [{date: 'dateString'}, ...
      const grouped = days.reduce((acc, el) => {
        if (!acc[el.date]) acc[el.date] = [];
        acc[el.date].push(el);
        return acc;
      }, {});
      return Object.keys(grouped).map(date => {
        return { date, count: grouped[date].length };
      });
    }
    

    Use that in a function fixes object's days prop

    // given an object with a days prop, remove dup days
    function removeObjectDupDays(object) {
      return { ...object, days: removeDupDays(object.days) };
    }
    

    Map that over the initial array...

    const arrayWithoutDupDays = initialArr.map(removeObjectDupDays);