Search code examples
javascriptapexcharts

JS filter array or arrays with unknown length?


I have some data I'm trying to transform by filtering by date, however the data can vary in length i.e like this;

longData = [
     // These objects could be unlimited but the name key will always be unique
    {name: Opt 1,
     Data:
         // The first value will always be a date string and the second is the amount, the length of this array is always unknown
         ['2021-01-02', 30],
         ['2021-01-03, 20],
         ['2021-02-05', 15]
     },
     {name: Opt 2,
     Data:
         ['2021-01-02', 30],
         ['2021-02-08, 20],
         ['2021-04-02, 15]
     },
     {name: Opt 3,
     Data:
         ['2021-03-02', 30],
         ['2021-03-04, 20]
     }

What I want to do is essentially create a new object that has the same shape and the original but only includes the data between my dates.

I.e if I have a start date of '2021-01-01' and end of date '2021-01-07'

I should get an object like the following..

shortData = [
    {name: Opt 1,
     Data:
         ['2021-01-02', 30],
         ['2021-01-03, 20]
     },
     {name: Opt 2,
     Data:
         ['2021-01-02', 30]
     },
     {name: Opt 3,
     Data:
         []
     }

I'm trying to break it down by week, these numbers are rendered in a chart and when dealing with large data sets it can break the chart essentially, so I'm trying to page it by week.

Any thoughts on how to accomplish it would be rather helpful.


Solution

  • You can create a function filterByDate which takes your start date and end date strings and converts them into date objects. Then, for each object in longData, you can map it to a transformed object containing a new Data property, which is the filtered version of your Data array.

    const longData = [{ name: "Opt 1", Data: [ ['2021-01-02', 30], ['2021-01-03', 20], ['2021-02-05', 15] ] }, { name: "Opt 2", Data: [ ['2021-01-02', 30], ['2021-02-0', 8, 20], ['2021-04-02', 15] ] }, { name: "Opt 3", Data: [ ['2021-03-02', 30], ['2021-03-04', 20] ] } ];
    
    const isBetween = (dx, d1, d2) => d1 < dx && dx < d2;
    const filterByDate = (data, start, end) => {
      const startDate = new Date(start);
      const endDate = new Date(end);
      return data.map(obj => ({...obj, Data: obj.Data.filter(
        ([date]) => isBetween(new Date(date), startDate, endDate)
      )}));
    }
    
    const res = filterByDate(longData, '2021-01-01', '2021-01-07');
    console.log(res);