Search code examples
javascripttypescriptlodashdata-conversionconverters

convert list of items to ranges based on object property


I've been struggling with this way too long. How would you approach the following in JavaScript. The source data contains objects indicating a date and a certain length. This list needs to be converted to a range-thingy like object which indicates on which day a certain length starts and ends.

If there is day missing this should be another range. So if I would remove day 33 in the example it would end up in 1 extra range object (one from 31 til 32, another one from 34 til 35)

    const data = [
      { day: 31, length: 10 },
      { day: 32, length: 10 },
      { day: 33, length: 10 },
      { day: 34, length: 10 },
      { day: 35, length: 10 },
      
      { day: 68, length: 15 },
      { day: 69, length: 15 },
      { day: 70, length: 15 },
      { day: 71, length: 15 },
      
      { day: 80, length: 10 },
      { day: 81, length: 10 },
      
      { day: 98, length: 12 },
      { day: 99, length: 12 },
      { day: 100, length: 30 },
    ];


    const convertToWindows = (data) => {
      return ...;
    };

    const windows = [
      {
        start: 31,
        end: 35,
        length: 10,
      },
      {
        start: 68,
        end: 71,
        length: 15,
      },
      {
        start: 80,
        end: 81,
        length: 10,
      },
      {
        start: 98,
        end: 99,
        length: 12,
      },
      {
        start: 100,
        end: 100,
        length: 30,
      },
    ];

Solution

  • Try something like this:

    const data = [
          { day: 31, length: 10 },
          { day: 32, length: 10 },
          { day: 33, length: 10 },
          { day: 34, length: 10 },
          { day: 35, length: 10 },
          
          { day: 68, length: 15 },
          { day: 69, length: 15 },
          { day: 70, length: 15 },
          { day: 71, length: 15 },
          
          { day: 80, length: 10 },
          { day: 81, length: 10 },
          
          { day: 98, length: 12 },
          { day: 99, length: 12 },
          { day: 100, length: 30 },
        ];
    
        const convertToWindows = (data) => {
          let result = [];
          data.forEach(v => {
            let rl = result.length;
            if (rl === 0 || result[rl-1].end + 1 !== v.day || result[rl-1].length !== v.length) {
              result.push({start: v.day, end: v.day, length: v.length});
            } else result[rl-1].end += 1;
          });
          return result;
        };
    
        console.log(convertToWindows(data));