Last active
October 9, 2023 10:21
-
-
Save th3terrorist/1d72fb10c7b2a1ddaa6283212f14738d to your computer and use it in GitHub Desktop.
Deeply merge js objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Merges two arrays by concatenating their elements uniquely using `new Set(...)`. | |
* | |
* @param {Array} a1 - The first array to merge. | |
* @param {Array} a2 - The second array to merge. | |
* @returns {Array} A new array containing elements from both input arrays. | |
*/ | |
const mergeArray = (a1, a2) => Array.from(new Set([...a1, ...a2])) | |
/** | |
* Recursively merges two objects based on their types and structure. | |
* | |
* @param {*} o1 - The first object to merge. | |
* @param {*} o2 - The second object to merge. | |
* @returns {*} A new object that is a merge of the two input objects. | |
* @throws {Error} Throws an error if either input is not an object. | |
*/ | |
const merge = (o1, o2) => { | |
if (typeof o1 === 'undefined') return o2 | |
if (typeof o1 !== typeof o2) return undefined | |
if (Array.isArray(o1) && Array.isArray(o2)) return mergeArray(o1, o2) | |
// They're some other type, prioritize the second object as there is no merge strategy | |
if (typeof o1 !== 'object') return o2 | |
return Object.keys(o2).reduce((acc, k) => { | |
const result = merge(o1[k], o2[k]) | |
return result ? { ...acc, [k]: result } : acc | |
}, o1) | |
} | |
/** | |
* Deeply merges two objects by recursively combining their properties. | |
* | |
* @param {Object} o1 - The first object to merge. | |
* @param {Object} o2 - The second object to merge. | |
* @returns {Object} A new object that is a deep merge of the two input objects. | |
* @throws {Error} Throws an error if either input is not an object. | |
*/ | |
const deepMerge = (o1, o2) => { | |
if (typeof o1 !== 'object') | |
throw new Error(`First argument should an object got: ${typeof o1}`) | |
if (typeof o2 !== 'object') | |
throw new Error(`Second argument should an object got: ${typeof o2}`) | |
return merge(o1, o2) | |
} | |
/** | |
* Deeply merges an array of objects into a single object, applying a recursive merge operation. | |
* | |
* @param {Array} arr - An array of objects to merge. | |
* @returns {Object} A new object that is a deep merge of all objects in the input array. | |
* @throws {Error} Throws an error if any element in the array is not an object. | |
*/ | |
const deepMergeAll = (...[head, ...tail]) => | |
tail?.length ? tail.reduce((acc, o) => deepMerge(acc, o), head) : head |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment