From ddbcb90c1fbb0f4be0431edfa999810353da5fd3 Mon Sep 17 00:00:00 2001 From: "D. Berge" Date: Wed, 30 Aug 2023 13:37:01 +0200 Subject: [PATCH] Add deepMerge() utility function --- lib/www/server/lib/utils/deepMerge.js | 67 +++++++++++++++++++++++++++ lib/www/server/lib/utils/index.js | 3 +- 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 lib/www/server/lib/utils/deepMerge.js diff --git a/lib/www/server/lib/utils/deepMerge.js b/lib/www/server/lib/utils/deepMerge.js new file mode 100644 index 0000000..4c98e49 --- /dev/null +++ b/lib/www/server/lib/utils/deepMerge.js @@ -0,0 +1,67 @@ +// Copied from: +// https://gomakethings.com/how-to-deep-merge-arrays-and-objects-with-javascript/ + +/*! + * Deep merge two or more objects or arrays. + * (c) 2023 Chris Ferdinandi, MIT License, https://gomakethings.com + * @param {*} ...objs The arrays or objects to merge + * @returns {*} The merged arrays or objects + */ +function deepMerge (...objs) { + + /** + * Get the object type + * @param {*} obj The object + * @return {String} The object type + */ + function getType (obj) { + return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); + } + + /** + * Deep merge two objects + * @return {Object} + */ + function mergeObj (clone, obj) { + for (let [key, value] of Object.entries(obj)) { + let type = getType(value); + if (clone[key] !== undefined && getType(clone[key]) === type && ['array', 'object'].includes(type)) { + clone[key] = deepMerge(clone[key], value); + } else { + clone[key] = structuredClone(value); + } + } + } + + // Create a clone of the first item in the objs array + let clone = structuredClone(objs.shift()); + + // Loop through each item + for (let obj of objs) { + + // Get the object type + let type = getType(obj); + + // If the current item isn't the same type as the clone, replace it + if (getType(clone) !== type) { + clone = structuredClone(obj); + continue; + } + + // Otherwise, merge + if (type === 'array') { + // Replace old array with new + clone = [...structuredClone(obj)]; + } else if (type === 'object') { + mergeObj(clone, obj); + } else { + clone = obj; + } + + } + + return clone; + +} + +module.exports = deepMerge; diff --git a/lib/www/server/lib/utils/index.js b/lib/www/server/lib/utils/index.js index 1d56a1a..d93ca92 100644 --- a/lib/www/server/lib/utils/index.js +++ b/lib/www/server/lib/utils/index.js @@ -3,5 +3,6 @@ module.exports = { geometryAsString: require('./geometryAsString'), dms: require('./dms'), replaceMarkers: require('./replaceMarkers'), - flattenQCDefinitions: require('./flattenQCDefinitions') + flattenQCDefinitions: require('./flattenQCDefinitions'), + deepMerge: require('./deepMerge') };