Comparing two array and adding missing objects in JS

Viewed 1127

I have two big arrays I want to compare both arrays and add missing data from arrayOne to arrayTwo

this is my some of the data

const arrayOne = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "81" },
      { x: "01-03", y: "361" },
      { x: "01-04", y: "64" },
      { x: "01-05", y: "169" },
      { x: "01-06", y: "9" },
      { x: "01-07", y: "100" },
      { x: "01-08", y: "144" },
      { x: "01-09", y: "81" },
      { x: "01-10", y: "256" },
      { x: "01-11", y: "81" },
      { x: "01-12", y: "144" },
      { x: "01-13", y: "144" },
      { x: "01-14", y: "225" },
      { x: "01-15", y: "289" },
      { x: "01-16", y: "81" },
      { x: "01-17", y: "64" },
      { x: "01-18", y: "64" },
      { x: "01-19", y: "121" },
      { x: "01-20", y: "25" },
      { x: "01-21", y: "49" },
      { x: "01-22", y: "16" },
      { x: "01-23", y: "49" },
      { x: "01-24", y: "196" },
      { x: "01-25", y: "16" },
      { x: "01-26", y: "25" },
      { x: "01-27", y: null },
      { x: "01-28", y: "144" },
      { x: "01-29", y: "100" },
      { x: "01-30", y: "64" },
      { x: "01-31", y: "144" },
      { x: "02-01", y: "100" },
      { x: "02-02", y: "100" },
      { x: "02-03", y: "49" },
    ],
  },
];

const arrayTwo = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "64" },
      { x: "01-03", y: "25" },
      { x: "01-04", y: "25" },
      { x: "01-05", y: "169" },
      { x: "01-15", y: "64" },
      { x: "01-16", y: "121" },
      { x: "01-17", y: "49" },
      { x: "01-18", y: "81" },
      { x: "01-19", y: "49" },
    ],
  },
];

I have tried to map it and compare it with respect to x but i am not able to achieve desirable output

arrayOne[0].data.map((date, index) => {
    arrayTwo[0].data.map((newDate, newIndex) => {
  if (date.x !== newDate.x) {
      arrayTwo[0].data.push({x:date.x, y: null })
    }
    });
  });

I want to check if data is missing from arrayTwo[data] if it is missing then add that data from arrayOne[data] (i.e. take the object with its x-value but set the y-value to null)

Desired output:

[
  {
    "id":"This Year",
    "data":[
      {"x":"01-02", "y":"64"},
      {"x":"01-03", "y":"25"},
      {"x":"01-04", "y":"25"},
      {"x":"01-05", "y":"169"},
      {"x":"01-06", "y":null},
      {"x":"01-07", "y":null},
      {"x":"01-08", "y":null},
      {"x":"01-09", "y":null},
      {"x":"01-10", "y":null},
      {"x":"01-11", "y":null},
      {"x":"01-12", "y":null},
      {"x":"01-13", "y":null},
      {"x":"01-14", "y":null},
      {"x":"01-15", "y":"64"},
      {"x":"01-16", "y":"121"},
      {"x":"01-17", "y":"49"},
      {"x":"01-18", "y":"81"},
      {"x":"01-19", "y":"49"},
      {"x":"01-20", "y":null},
      {"x":"01-21", "y":null},
      {"x":"01-22", "y":null},
      {"x":"01-23", "y":null},
      {"x":"01-24", "y":null},
      {"x":"01-25", "y":null},
      {"x":"01-26", "y":null},
      {"x":"01-27", "y":null},
      {"x":"01-28", "y":null},
      {"x":"01-29", "y":null},
      {"x":"01-30", "y":null},
      {"x":"01-31", "y":null},
      {"x":"02-01", "y":null},
      {"x":"02-02", "y":null},
      {"x":"02-03", "y":null}
    ]
  }
]
2 Answers

You can do it like this:

  • create an object (objOne) from arrayOne[0].data using reduce
  • overwrite any property of the objOne if the key is present in arrayTwo[0].data, again using reduce and using objOne as the initial value.
  • convert this objOne to an array with Object.values(objOne) and then set that as the property of arrayTwo[0].data

Time complexity should be O(n + m) for the two reduce functions (where n and m are the length of the two arrays). (Should be faster than using find for every element in one of the arrays)

Key part of the code:

const objOne = arrayOne[0].data.reduce((aggObj, item) => {
  aggObj[item.x] = item;  
  return aggObj;
}, {});

const mergedObjOutput = arrayTwo[0].data.reduce((aggObj, item) => {
  aggObj[item.x] = item;  
  return aggObj;
}, objOne)

const mergedFinalOutput = [...arrayTwo];
mergedFinalOutput[0].data = Object.values(mergedObjOutput);

console.log(mergedFinalOutput);

Full demo:

const arrayOne = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "81" },
      { x: "01-03", y: "361" },
      { x: "01-04", y: "64" },
      { x: "01-05", y: "169" },
      { x: "01-06", y: "9" },
      { x: "01-07", y: "100" },
      { x: "01-08", y: "144" },
      { x: "01-09", y: "81" },
      { x: "01-10", y: "256" },
      { x: "01-11", y: "81" },
      { x: "01-12", y: "144" },
      { x: "01-13", y: "144" },
      { x: "01-14", y: "225" },
      { x: "01-15", y: "289" },
      { x: "01-16", y: "81" },
      { x: "01-17", y: "64" },
      { x: "01-18", y: "64" },
      { x: "01-19", y: "121" },
      { x: "01-20", y: "25" },
      { x: "01-21", y: "49" },
      { x: "01-22", y: "16" },
      { x: "01-23", y: "49" },
      { x: "01-24", y: "196" },
      { x: "01-25", y: "16" },
      { x: "01-26", y: "25" },
      { x: "01-27", y: null },
      { x: "01-28", y: "144" },
      { x: "01-29", y: "100" },
      { x: "01-30", y: "64" },
      { x: "01-31", y: "144" },
      { x: "02-01", y: "100" },
      { x: "02-02", y: "100" },
      { x: "02-03", y: "49" },
    ],
  },
];

const arrayTwo = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "64" },
      { x: "01-03", y: "25" },
      { x: "01-04", y: "25" },
      { x: "01-05", y: "169" },
      { x: "01-15", y: "64" },
      { x: "01-16", y: "121" },
      { x: "01-17", y: "49" },
      { x: "01-18", y: "81" },
      { x: "01-19", y: "49" },
    ],
  },
];

const objOne = arrayOne[0].data.reduce((aggObj, item) => {
  aggObj[item.x] = item;  
  return aggObj;
}, {});

const mergedObjOutput = arrayTwo[0].data.reduce((aggObj, item) => {
  aggObj[item.x] = item;  
  return aggObj;
}, objOne)

const mergedFinalOutput = [...arrayTwo];
mergedFinalOutput[0].data = Object.values(mergedObjOutput);

console.log(mergedFinalOutput);
.as-console-wrapper { max-height: 100% !important; top: 0; }

UPDATE

If you really want your output like this (from your clarification in the comments under your question):

[
  {
    "id":"This Year",
    "data":[
      {"x":"01-02", "y":"64"},
      {"x":"01-03", "y":"25"},
      {"x":"01-04", "y":"25"},
      {"x":"01-05", "y":"169"},
      {"x":"01-06", "y":null},
      {"x":"01-07", "y":null},
      {"x":"01-08", "y":null},
      {"x":"01-09", "y":null},
      {"x":"01-10", "y":null},
      {"x":"01-11", "y":null},
      {"x":"01-12", "y":null},
      {"x":"01-13", "y":null},
      {"x":"01-14", "y":null},
      {"x":"01-15", "y":"64"},
      {"x":"01-16", "y":"121"},
      {"x":"01-17", "y":"49"},
      {"x":"01-18", "y":"81"},
      {"x":"01-19", "y":"49"},
      {"x":"01-20", "y":null},
      {"x":"01-21", "y":null},
      {"x":"01-22", "y":null},
      {"x":"01-23", "y":null},
      {"x":"01-24", "y":null},
      {"x":"01-25", "y":null},
      {"x":"01-26", "y":null},
      {"x":"01-27", "y":null},
      {"x":"01-28", "y":null},
      {"x":"01-29", "y":null},
      {"x":"01-30", "y":null},
      {"x":"01-31", "y":null},
      {"x":"02-01", "y":null},
      {"x":"02-02", "y":null},
      {"x":"02-03", "y":null}
    ]
  }
]

Then this is the demo:

const arrayOne = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "81" },
      { x: "01-03", y: "361" },
      { x: "01-04", y: "64" },
      { x: "01-05", y: "169" },
      { x: "01-06", y: "9" },
      { x: "01-07", y: "100" },
      { x: "01-08", y: "144" },
      { x: "01-09", y: "81" },
      { x: "01-10", y: "256" },
      { x: "01-11", y: "81" },
      { x: "01-12", y: "144" },
      { x: "01-13", y: "144" },
      { x: "01-14", y: "225" },
      { x: "01-15", y: "289" },
      { x: "01-16", y: "81" },
      { x: "01-17", y: "64" },
      { x: "01-18", y: "64" },
      { x: "01-19", y: "121" },
      { x: "01-20", y: "25" },
      { x: "01-21", y: "49" },
      { x: "01-22", y: "16" },
      { x: "01-23", y: "49" },
      { x: "01-24", y: "196" },
      { x: "01-25", y: "16" },
      { x: "01-26", y: "25" },
      { x: "01-27", y: null },
      { x: "01-28", y: "144" },
      { x: "01-29", y: "100" },
      { x: "01-30", y: "64" },
      { x: "01-31", y: "144" },
      { x: "02-01", y: "100" },
      { x: "02-02", y: "100" },
      { x: "02-03", y: "49" },
    ],
  },
];

const arrayTwo = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "64" },
      { x: "01-03", y: "25" },
      { x: "01-04", y: "25" },
      { x: "01-05", y: "169" },
      { x: "01-15", y: "64" },
      { x: "01-16", y: "121" },
      { x: "01-17", y: "49" },
      { x: "01-18", y: "81" },
      { x: "01-19", y: "49" },
    ],
  },
];

const objOne = arrayOne[0].data.reduce((aggObj, item) => {
  aggObj[item.x] = {...item, y: null};  
  return aggObj;
}, {});

const mergedObjOutput = arrayTwo[0].data.reduce((aggObj, item) => {
  aggObj[item.x] = item;  
  return aggObj;
}, objOne)

const mergedFinalOutput = [...arrayTwo];
mergedFinalOutput[0].data = Object.values(mergedObjOutput);

console.log(mergedFinalOutput);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Try something like this:

Loop through the elements, if they aren't found in the first array add them to the second array

const arrayOne = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "81" },
      { x: "01-03", y: "361" },
      { x: "01-04", y: "64" },
      { x: "01-05", y: "169" },
      { x: "01-06", y: "9" },
      { x: "01-07", y: "100" },
      { x: "01-08", y: "144" },
      { x: "01-09", y: "81" },
      { x: "01-10", y: "256" },
      { x: "01-11", y: "81" },
      { x: "01-12", y: "144" },
      { x: "01-13", y: "144" },
      { x: "01-14", y: "225" },
      { x: "01-15", y: "289" },
      { x: "01-16", y: "81" },
      { x: "01-17", y: "64" },
      { x: "01-18", y: "64" },
      { x: "01-19", y: "121" },
      { x: "01-20", y: "25" },
      { x: "01-21", y: "49" },
      { x: "01-22", y: "16" },
      { x: "01-23", y: "49" },
      { x: "01-24", y: "196" },
      { x: "01-25", y: "16" },
      { x: "01-26", y: "25" },
      { x: "01-27", y: null },
      { x: "01-28", y: "144" },
      { x: "01-29", y: "100" },
      { x: "01-30", y: "64" },
      { x: "01-31", y: "144" },
      { x: "02-01", y: "100" },
      { x: "02-02", y: "100" },
      { x: "02-03", y: "49" }
    ]
  }
];

const arrayTwo = [
  {
    id: "This Year",
    data: [
      { x: "01-02", y: "64" },
      { x: "01-03", y: "25" },
      { x: "01-04", y: "25" },
      { x: "01-05", y: "169" },
      { x: "01-15", y: "64" },
      { x: "01-16", y: "121" },
      { x: "01-999", y: "49" },
      { x: "01-18", y: "81" },
      { x: "01-19", y: "49" }
    ]
  }
];

console.log(arrayOne);
arrayTwo[0].data.forEach(obj => {
  const found = arrayOne[0].data.find(obj2 => obj2.x === obj.x);
  if (!found) {
    arrayOne[0].data.push(obj);
  }
});

console.log(arrayOne);

Related