add deepMerge utility function

This commit is contained in:
Josh de Leeuw 2023-05-16 21:35:20 -04:00
parent d0a6839ac2
commit 236cac8a21
2 changed files with 82 additions and 1 deletions

View File

@ -28,3 +28,34 @@ export function deepCopy(obj) {
return obj;
}
}
/**
* Merges two objects, recursively.
* @param obj1 Object to merge
* @param obj2 Object to merge
*/
export function deepMerge(obj1: any, obj2: any): any {
let merged = {};
for (const key in obj1) {
if (obj1.hasOwnProperty(key)) {
if (typeof obj1[key] === "object" && obj2.hasOwnProperty(key)) {
merged[key] = deepMerge(obj1[key], obj2[key]);
} else {
merged[key] = obj1[key];
}
}
}
for (const key in obj2) {
if (obj2.hasOwnProperty(key)) {
if (!merged.hasOwnProperty(key)) {
merged[key] = obj2[key];
} else if (typeof obj2[key] === "object") {
merged[key] = deepMerge(merged[key], obj2[key]);
} else {
merged[key] = obj2[key];
}
}
}
return merged;
}

View File

@ -1,4 +1,4 @@
import { deepCopy, unique } from "../../src/modules/utils";
import { deepCopy, deepMerge, unique } from "../../src/modules/utils";
describe("unique", () => {
test("generates unique array when there are duplicates", () => {
@ -44,3 +44,53 @@ describe("deepCopy", () => {
expect(o2.b()).toBe(1);
});
});
describe("deepMerge", () => {
it("should merge two objects with nested properties", () => {
const obj1 = { a: 1, b: { c: { d: 1 } } };
const obj2 = { b: { c: { e: 2 } }, f: 3 };
const expected = { a: 1, b: { c: { d: 1, e: 2 } }, f: 3 };
const result = deepMerge(obj1, obj2);
expect(result).toEqual(expected);
});
it("should overwrite properties in obj1 with properties in obj2", () => {
const obj1 = { a: 1, b: { c: { d: 1 } } };
const obj2 = { a: 2, b: { c: { d: 2 } } };
const expected = { a: 2, b: { c: { d: 2 } } };
const result = deepMerge(obj1, obj2);
expect(result).toEqual(expected);
});
it("should handle null and undefined values", () => {
const obj1 = { a: null, b: { c: undefined } };
const obj2 = { a: 1, b: { c: { d: 1 } } };
const expected = { a: 1, b: { c: { d: 1 } } };
const result = deepMerge(obj1, obj2);
expect(result).toEqual(expected);
});
it("should handle empty objects", () => {
const obj1 = { a: 1, b: {} };
const obj2 = { b: { c: 2 } };
const expected = { a: 1, b: { c: 2 } };
const result = deepMerge(obj1, obj2);
expect(result).toEqual(expected);
});
it("should handle when one property is an object and the corresponding property is not", () => {
const obj1 = { a: 1, b: { c: { d: 1 } } };
const obj2 = { a: 2, b: 3 };
const expected = { a: 2, b: 3 };
const result = deepMerge(obj1, obj2);
expect(result).toEqual(expected);
});
it("should handle when one property is an object and the corresponding property is not, reversed", () => {
const obj1 = { a: 1, b: { c: { d: 1 } } };
const obj2 = { a: 2, b: 3 };
const expected = { a: 1, b: { c: { d: 1 } } };
const result = deepMerge(obj2, obj1);
expect(result).toEqual(expected);
});
});