Skip to content

Instantly share code, notes, and snippets.

@Wallacy
Created May 23, 2020 21:35
Show Gist options
  • Save Wallacy/adf546f4de34848e8355d6a511d89647 to your computer and use it in GitHub Desktop.
Save Wallacy/adf546f4de34848e8355d6a511d89647 to your computer and use it in GitHub Desktop.
Just sharing my deepMerge
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