Search code examples
arraystypescriptobject

Need to a compare the two array objects and create a new array of objects


Array structure

let array1 = [
  {
    '2023-08-03': { x: 179.159093242013, y: null },
    '2023-08-04': { x: 178.323000340271, y: 55.727942469807 },
    '2023-08-05': { x: null, y: 56.727774687963 },
    '2023-08-06': { x: 182.232246437691, y: 48.911777872434 },
    '2023-08-07': { x: null, y: null },
    '2023-08-08': { x: 180.147793830328, y: 57.752356407584 },
    '2023-08-09': { x: null, y: 47.714833999144 }
  }
] 
let array2 = [
  {
    '2023-07-03': { x: null, y: 45.2 },
    '2023-07-04': { x: 180.55307760927744, y: 48.4 },
    '2023-07-05': { x: 180.04640371229698, y: 55.8 },
    '2023-07-06': { x: 180.53989728172365, y: 57.4 },
    '2023-08-07': { x: null, y: null },
    '2023-07-08': { x: 168.59344894026975, y: 37.3 },
    '2023-07-09': { x: 178.7709497206704, y: 57.9 }
  }
]

I need to compare above two arrays and build a new one , but there are some condition like

  1. if x value in array1 is null, then it should take the value from x in array2 on same date.
  2. If y value in array1 is null, then it should take the value from y in array2 on same date.
  3. If x & y values in array1 is not null , then no need to take value from array2 Like that I need to build a single array of objects

expected output should be like

let newArray = [{
    '2023-08-03': { x: 179.159093242013, y: 45.2 },
    '2023-08-04': { x: 178.323000340271, y: 55.727942469807 },
    '2023-08-05': { x: 180.04640371229698, y: 56.727774687963 },
    '2023-08-06': { x: 182.232246437691, y: 48.911777872434 },
    '2023-08-07': { x: null, y: null },
    '2023-08-08': { x: 180.147793830328, y: 57.752356407584 },
    '2023-08-09': { x: 178.7709497206704, y: 47.714833999144 }
}
]

Please help

I have tried many method, but nothing is working.


Solution

  • First, let's create a type for the array type:

    type ArrType = Record<string, { x: number | null; y: number | null }>[];
    

    Now, let's write a merge function that will accept two ArrType arguments and merge them into one.

    To iterate over the array were are going to use Array.prototype.reduce() and the accumulated value we a new array. Then, using the Object.entries(), which will give us an array of tuples where the first element is the key and the second one is the value ({x: type, y: type}). Using Array.prototype.map() we are going to mutate the value in the entries to a new value using the nullish coalescing operator according to the rules described in the OP. The last step is to convert the new tuples to an object, which can be done using Object.fromEntries. Then, we will push the new object to the accumulated value:

    const merge = (arr1: ArrType, arr2: ArrType) => {
      return arr1.reduce<ArrType>((acc, obj, index) => {
        acc.push(
          Object.fromEntries(
            Object.entries(obj).map(([key, value]) => [
              key,
              {
                x: value.x ?? arr2[index][key]?.x ?? null,
                y: value.y ?? arr2[index][key]?.y ?? null,
              },
            ]),
          ),
        );
    
        return acc;
      }, []);
    };
    

    playground