@augment-vir/common
Version:
A collection of augments, helpers types, functions, and classes for any JavaScript environment.
53 lines (52 loc) • 1.79 kB
JavaScript
import { check } from '@augment-vir/assert';
/**
* Accepts multiple objects and merges their key-value pairs recursively. Any values set to
* undefined will be removed.
*
* Note that order matters! Each input object will overwrite the properties of the previous objects.
*
* @category Object : Merge
* @category Package : @augment-vir/common
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
*/
export function mergeDeep(...inputs) {
if (!check.isLengthAtLeast(inputs, 1)) {
// nothing to merge if no inputs
return {};
}
if (inputs.length === 1) {
// nothing to merge if only one input
return inputs[0];
}
let result = undefined;
const mergeProps = {};
inputs.forEach((individualInput) => {
if (!check.isObject(individualInput)) {
/** If not an object, we can't merge. So overwrite instead. */
result = individualInput;
return;
}
else if (!check.isObject(result)) {
/** If result isn't an object then we need to make it into one. */
result = { ...individualInput };
}
Object.entries(individualInput).forEach(([key, value,]) => {
if (!mergeProps[key]) {
mergeProps[key] = [];
}
mergeProps[key].push(value);
});
});
if (check.isObject(result)) {
Object.entries(mergeProps).forEach(([key, mergeValues,]) => {
const newValue = mergeDeep(...mergeValues);
if (newValue === undefined && key in result) {
delete result[key];
}
else if (newValue !== undefined) {
result[key] = newValue;
}
});
}
return result;
}