Skip to content

Commit

Permalink
Merge pull request #63 from likhith-deriv/likhith/create-custom-merge…
Browse files Browse the repository at this point in the history
…-function

Likhith/create custom merge function
  • Loading branch information
niloofar-deriv authored Jul 15, 2024
2 parents ae968b9 + 5ff3441 commit 16ae82b
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/utils/__test__/object.utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,28 @@ describe("hashObject", () => {
expect(output1).toEqual(output2);
});
});

describe("merge", () => {
test("should merge two objects", () => {
const target = { a: 1, b: 2 };
const source = { b: 3, c: 4 };
const output = ObjectUtils.merge(target, source);
expect(output).toEqual({ a: 1, b: 3, c: 4 });
});

test("should merge nested objects", () => {
type Test = {
a: {
b?: string[] | null;
c?: number;
d?: number;
};
};

const target: Test = { a: { c: 2, b: null } };
const source1 = { a: { d: 4 } };
const source2 = { a: { b: ["apple", "bat"] } };
const output = ObjectUtils.merge(target, source1, source2);
expect(output).toEqual({ a: { b: ["apple", "bat"], c: 2, d: 4 } });
});
});
31 changes: 31 additions & 0 deletions src/utils/object.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,34 @@ export const hashObject = async <T extends object>(object: T) => {
const hashedString = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("");
return hashedString;
};

type TSources<T> = {
[P in keyof T]?: TSources<T[P]>;
};

const replaceValue = <T>(value: T, newValue: T): T => {
if (Array.isArray(value) && Array.isArray(newValue)) {
return newValue.map((v, i) => replaceValue(value[i], v)) as unknown as T;
} else if (typeof value === "object" && value !== null && typeof newValue === "object" && newValue !== null) {
return merge(value, newValue);
}
return newValue;
};

/**
* Function to merge two objects. An alternate to lodash.merge
* @param target - The object to be merged into
* @param sources - The objects to merge into target
* @returns The merged object
*/
export const merge = <T>(target: T, ...sources: TSources<T>[]): T => {
for (const source of sources) {
for (const key in source) {
if (source[key] === null || source[key] === undefined) {
continue;
}
target[key as keyof T] = replaceValue(target[key as keyof T], source[key]!) as T[keyof T];
}
}
return target;
};
13 changes: 13 additions & 0 deletions utils-docs/docs/Utils/object.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,16 @@ It throws an error if the hashing operation fails or if the input is not a valid
#### Options

`object: T[required]` - The object to be hashed.

### merge

Deeply merges multiple source objects into a target object. It merges individual values excluding null and undefined. It concatenates arrays. recursively merges objects and directly assigns functions

#### Options

- `target: T` - The target object to merge into.
- `sources: DeepPartial<T>[]` - One or more source objects to merge into the target.

#### Returns

- `T` - The merged target object.

0 comments on commit 16ae82b

Please sign in to comment.