Last active
April 17, 2019 22:37
-
-
Save supasympa/22f3421013582f7024486bdfcba79eef to your computer and use it in GitHub Desktop.
A cheap deep merge
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
const { keys } = Object; | |
const isObject = a => typeof a === "object" && !Array.isArray(a); | |
const bothObjects = (a, b) => isObject(a) && isObject(b); | |
const neitherObjects = (a, b) => !isObject(a) && !isObject(b); | |
const sameType = (a, b) => (typeof a === typeof b); | |
const merge = (a, b) => | |
bothObjects(a, b)? | |
deepMerge(a, b): | |
isObject(a) && !isObject(b)? | |
a: | |
b; | |
// swap merge for concatenation / summation with this: | |
const addOrMerge = (a, b) => | |
neitherObjects(a, b) && sameType(a, b)? | |
(a + b): | |
merge(a,b); | |
const coalesceByKey = source => (acc, key) => | |
(acc[key] && source[key] | |
? (acc[key] = merge(acc[key], source[key])) | |
: (acc[key] = source[key])) && acc; | |
/** | |
* Merge all sources into the target | |
* overwriting primitive values in the the accumulated target as we go (if they already exist) | |
* @param {*} target | |
* @param {...any} sources | |
*/ | |
const deepMerge = (target, ...sources) => | |
sources.reduce( | |
(acc, source) => keys(source).reduce(coalesceByKey(source), acc), | |
target | |
); | |
console.log(deepMerge({ a: 1 }, { a: 2 })); | |
console.log(deepMerge({ a: 1 }, { a: { b: 2 } })); | |
console.log(deepMerge({ a: { b: 2 } }, { a: 1 })); | |
console.log( | |
deepMerge( | |
{ a: 1, d: ["foo"] }, | |
{ d: { dd: 99 } }, | |
{ c: 3, d: { e: 4 } }, | |
{ f: 100, g: ["bar"] } | |
) | |
); | |
console.log( | |
deepMerge( | |
{ name: "simple" }, | |
{ | |
name: "complex", | |
index: 1, | |
type: "complex", | |
subType: { | |
name: "sub", | |
index: 2, | |
type: "simple", | |
subSubType: { | |
name: "sub-sub", | |
age: 3, | |
type: "simple" | |
} | |
} | |
}, | |
{ | |
name: "complex", | |
index: 4, | |
type: "complex", | |
subType: { | |
name: "sub", | |
index: 5, | |
type: "simple" | |
} | |
} | |
) | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment