I have two dynamic arrays of objects which I get from an API (the fields are created by an end user, I am not aware of the keys beforehand). One is original and the other is a modified version. I want to compare them and get the changed rowIndex on the modified one as well as which object properties have been changed. This is my code.
const originalData = [{
brand: 'Honda',
model: 'Accord'
}, {
brand: 'Honda',
model: 'Civic'
}, {
brand: 'Toyota',
model: 'Camry'
}, {
brand: 'Toyota',
model: 'Corolla'
}]
const data = [{
brand: 'Honda',
model: 'Accord'
}, {
brand: 'Honda',
model: 'CRV'
}, {
brand: 'Toyota',
model: 'Camry'
}, {
brand: 'Nissan',
model: 'RAV4'
}]
console.log(data.reduce((a, c, i, arr) => {
if (!originalData.some(j => {
return _.isEqual(c, j)
})) {
a.push({
rowIndex: i,
changedKeys: arr[i]
})
}
return a
}, []))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
I am not able to get the changedKeys here. I am able to get the object itself. How do I get the changed key?
Expected output:
[
{
"rowIndex": 1,
"changedKeys": ['model']
},
{
"rowIndex": 3,
"changedKeys": ['brand', 'model']
}
]
Please advice.
CodePudding user response:
Using reduce
. Iterate over the array of objects. Initialise an array called changedKeys
. Iterate over the keys/values in each object and if there's a mismatch, push the key into changedKeys
. Finally, if there are keys in changedKeys
push that into the accumulator for the next round of iteration.
const originalData=[{brand:"Honda",model:"Accord"},{brand:"Honda",model:"Civic"},{brand:"Toyota",model:"Camry"},{brand:"Toyota",model:"Corolla"},{brand:"Renault",model:"Clio"}],data=[{brand:"Honda",model:"Accord"},{brand:"Honda",model:"CRV"},{brand:"Toyota",model:"Camry"},{brand:"Nissan",model:"Corolla"},{brand:"Datsun",model:"Cherry"}];
const out = originalData.reduce((acc, obj, i) => {
// Initialise `changedKeys`
const changedKeys = [];
// Loop over the original object and compare the
// values to those in the new data set, pushing the
// key into `changedKeys` if there's a mismatch
for (const key in obj) {
if (obj[key] !== data[i][key]) {
changedKeys.push(key);
}
}
// If there are mismatches push an object into
// the accumulator with the index
if (changedKeys.length) {
acc.push({ rowIndex: i, changedKeys });
}
// Return the accumulator for the next iteration
return acc;
}, []);
console.log(out);
Additional documentation