let masterList = `[{"category_id":1,"meta_list":[{"name":"Cuisine","id":"QWEQWEQWE","is_multiselect":false,"item_list":["Arabian","Indian"]},{"name":"Cost for Two","id":"SFDFSDASDASDASD","is_multiselect":true,"item_list":["AED 0 - 100","AED 100 - 200","Greater Than AED 200"]}]},{"category_id":2,"meta_list":[{"name":"Cat 2","id":"cat2","is_multiselect":false,"item_list":["cat 2 1","cat 2 2"]},{"name":"cuisine 2","id":"cui2","is_multiselect":true,"item_list":["cu1","cu2"]}]}]`;
let selectedList = `[{"category_id":1,"meta_list":[{"name":"Cuisine","id":"QWEQWEQWE","is_multiselect":false,"item_list":["Arabian"]},{"name":"Cost for Two","id":"SFDFSDASDASDASD","is_multiselect":true,"item_list":["AED 100 - 200","Greater Than AED 200"]}]},{"category_id":2,"meta_list":[{"name":"cuisine 2","id":"cui2","is_multiselect":true,"item_list":["cu1"]}]}]`;
/**
* Deep merges 2 objects (if a property exists for both objects then only the original will be used)
* @param {{} | string} original Original object in object or json format
* @param {{} | string} other Other object in object or json format
* @param {(original: string | {}, other: string | {}) => boolean} manageList Function called to compare items in the arrays
* @returns {{}}
*/
function mergeJSONs(original, other, manageList) {
original = typeof original === "string" ? original : JSON.stringify(original); // Deep clone both objects
other = typeof other === "string" ? other : JSON.stringify(other);
return recursiveMerge(JSON.parse(original), JSON.parse(other), manageList);
}
/**
* Copies all the properties that exist in the `other` object to the `original` object
* @param {{}} original Object to copy the properties to
* @param {{}} other Object to copy the properties from
* @param {(original: string | {}, other: string | {}) => boolean} manageList Function called to compare items in the arrays
* @returns {{}}
*/
function recursiveMerge(original, other, manageList) {
if (original instanceof Array) {
if (!(other instanceof Array)) throw Error("Incompatible Types");
var matchedList = [];
for (var otherItem of other) {
var originalIndex = original.findIndex(function(originalItem, index) {
if (manageList.call(this, originalItem, otherItem) && !matchedList.includes(index)) return matchedList.push(index);
});
if (originalIndex === -1) original.push(otherItem);
else if (typeof otherItem === "object") recursiveMerge(original[originalIndex], otherItem, manageList);
}
} else {
if (other instanceof Array) throw Error("Incompatible Types");
for (var key in other) {
if (!(key in original)) original[key] = other[key];
else if (typeof other[key] === "object") recursiveMerge(original[key], other[key], manageList);
}
}
return original;
}
console.log(mergeJSONs(masterList, selectedList.replace(/"item_list":/g, "\"sel_list\":"), function(original, other) {
if (typeof original === "string" && typeof other === "string") return original === other;
else if (typeof original === "object" && typeof other === "object") {
if ("category_id" in original && "category_id" in other) return original.category_id === other.category_id;
if ("id" in original && "id" in other) return original.id === other.id;
}
}));