Created
May 23, 2020 21:35
-
-
Save Wallacy/adf546f4de34848e8355d6a511d89647 to your computer and use it in GitHub Desktop.
Just sharing my deepMerge
This file contains 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
import { RecursivePartial } from "."; | |
function isObject(item: any): boolean { | |
return item && typeof item === "object" && !Array.isArray(item); | |
} | |
function prumeLength(target: any[], lengths = [] as number[]) { | |
lengths.push(target.length); | |
const getProto = (obj: any) => { | |
if (obj) { | |
if (obj.length) { | |
lengths.push(obj.length); | |
} | |
getProto(obj.__proto__); | |
} | |
}; | |
getProto((target as any).__proto__); | |
target.length = Math.max.apply(null, lengths); | |
} | |
/** | |
* Deep merge two or more objects with array merge. | |
* @param target | |
* @param ...sources | |
*/ | |
export function deepFullMerge<T>(target: any, ...sources: RecursivePartial<T>[]): T { | |
const pogSources = sources as any; | |
if (!pogSources.length) { | |
return target; | |
} | |
const source = pogSources.shift(); | |
deepMerges(target, source, true); | |
return deepFullMerge(target, ...pogSources); | |
} | |
/** | |
* Deep merge two or more objects without array merge.. | |
* @param target | |
* @param ...sources | |
*/ | |
export function deepMerge<T>(target: any, ...sources: RecursivePartial<T>[]): T { | |
const pogSources = sources as any; | |
if (!pogSources.length) { | |
return target; | |
} | |
const source = pogSources.shift(); | |
deepMerges(target, source, false); | |
return deepMerge(target, ...pogSources); | |
} | |
/** | |
* Deep merge two | |
* @param target | |
* @param source | |
*/ | |
function deepMerges<T>(target: any, source: RecursivePartial<T>, mergeArray = false): T { | |
const src = source as any; | |
if (isObject(target) && isObject(src)) { | |
const arr = Object.keys(src) | |
for (let idx = 0; idx < arr.length; idx++) { | |
const key = arr[idx]; | |
if (isObject(src[key])) { | |
if (Buffer.isBuffer(src[key])) { | |
target[key] = Buffer.from(src[key]); | |
} else { | |
if (!target.hasOwnProperty(key) || target[key] === undefined) { | |
Object.assign(target, { [key]: {} }); | |
} | |
deepMerges(target[key], src[key], mergeArray); | |
} | |
} else if (Array.isArray(src[key])) { | |
if (mergeArray && target.hasOwnProperty(key) && Array.isArray(target[key])) { | |
for (let sIdx = 0; sIdx < src[key].length; sIdx++) { | |
const val = src[key][sIdx]; | |
const hasItem = target[key].includes(val); | |
if (!hasItem) { | |
target[key].push(val); | |
} | |
} | |
prumeLength(target[key]); // remakes calculations of size on the array and its prototypes | |
} else { | |
target = Object.assign(target, { [key]: src[key] }); | |
} | |
} else { | |
target = Object.assign(target, { [key]: src[key] }); | |
} | |
} | |
} | |
return target; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment