I'm working to add, update or remove a nested object from an array based on the objects from another array. For example, I would like to update the date -> gte value based on the update array, while keeping entry -> eq and adding date -> lte.
I have attempted with the following snippet but the outcome produces an inflated result with incorrect keys/values.
const existing = [
{ date: { gte: '2021-01-01' } },
{ entry: { eq: 1 } },
{ keep: { eq: 100 } },
];
const update = [
{ date: { gte: '2021-02-01' } },
{ date: { lte: '2021-12-31' } },
];
const outcome = [];
update.forEach((el) => {
existing.forEach(elem => {
Object.entries(elem).forEach(([k, v]) => {
Object.entries(el).forEach(([key, value]) => {
if (k === key && Object.keys(v).sort().toString() === Object.keys(value).sort().toString()) {
outcome.push(el)
} else {
outcome.push(elem)
}
});
});
})
});
console.log(outcome);
// expected outcome
// [
// { date: { gte: '2021-02-01' } },
// { entry: { eq: 1 }},
// { keep: { eq: 100 } },
// { date: { lte: '2021-12-31' } }
// ]
// current outcome
// [
// { date: { gte: '2021-02-01' } },
// { entry: { eq: 1 } },
// { keep: { eq: 100 } },
// { date: { gte: '2021-01-01' } },
// { entry: { eq: 1 } },
// { keep: { eq: 100 } }
// ]
This should be enough for your case (updates inplace):
const existing = [
{ date: { gte: '2021-01-01' } },
{ entry: { eq: 1 } },
{ keep: { eq: 100 } },
];
const update = [
{ date: { gte: '2021-02-01' } },
{ date: { lte: '2021-12-31' } },
];
while (update.length) {
const u = update.shift();
const [p, o] = Object.entries(u)[0];
const [k, v] = Object.entries(o)[0];
const f = existing.find(e => p in e && k in e[p]);
f ? f[p][k] = v : existing.push(u);
}
console.log(existing);