David Sawatske
David Sawatske

Reputation: 111

How to parse array of objects, each object has a dates array, returning a unique dates array and two data arrays

I am struggling to come up with a way for format this data.

Desired Return: An object with 3 arrays

  1. a unique array of dates
  2. an array of data1 values the same length as the dates array, with null and the index that corresponds with the index in the dates array for which data1 does not have a value
  3. the same as 2, except for data1 values

The example shown below should give a better idea of what I am trying to solve.

Desired Result:

{ dates: ['Tue Jun 20 2018', 
          'Wed Jun 21 2018', 
          'Thu Jun 22 2018',
          'Fri Jun 23 2018',
          'Sat Jun 24 2018'],
  data1: [5, null, 12, null, 20]
  data2: [14, 4, 15, 2, null]
 }

Example Input: An array with multiple objects. Each object has a dates property

[
  { dates: ['Tue Jun 20 2018',
            'Thu Jun 22 2018',
            'Sat Jun 24 2018'],
    data1: [5, 12, 20]
  },
  { dates: ['Tue Jun 20 2018', 
            'Wed Jun 21 2018', 
            'Thu Jun 22 2018',
            'Fri Jun 23 2018'],
    data2: [14, 4, 15, 2]
  }
 ]

I can solve by creating two objects key value pairs for each input object, joining all dates into an array and making unique, mapping over the new dates array and inserting null values in each data array if that specific object does not have that date as a key.

Sorry for the long/ confusing explanation. Have a look at the input/ output and let me know how I can best solve this.

Thanks!

Upvotes: 1

Views: 97

Answers (1)

Jonas Wilms
Jonas Wilms

Reputation: 138257

Shift in new dates by adding null to all other rows:

 function merge(data, key, { dates = [], values = {} } = {}) {
   // Add the key to the resulting values
   if(!values[key]) values[key] = [];
   // Go over all dates of the data
   for(const [index, date] of data.dates.entries()) {
     // Add new dates by adding `null` to all keys
     if(!dates.includes(date)) {
       dates.push(date);     
       Object.values(values).forEach(arr => arr.push(null));
     }   
     // then copy the value from data to values
     const pos = dates.indexOf(date);
     values[key][pos] = data[key][index];
   }
   // also add a method for chaining
   return { dates, values, result: { dates, ...values }, merge(data, key){ return merge(data, key, this); }, };
}

Usable as:

 const { result } = 
    merge(arr[0], "data1")
   .merge(arr[1], "data2");

Upvotes: 1

Related Questions