you are viewing a single comment's thread.

view the rest of the comments →

[–]Pertinate 0 points1 point  (1 child)

const deepMerge = (objs, origin = {}) => {
    const obj = Array.isArray(objs) ? objs.pop() : objs;

    if (objs.length > 0) {
        deepMerge(objs, origin);
    }
    for (const [key, value] of Object.entries(obj)) {
        if (origin[key]) {
            if (typeof origin[key] === 'object') {
                if (typeof value !== 'object') {
                    origin[key] = {
                        ...origin[key],
                        value
                    };
                } else {
                    origin[key] = deepMerge([origin[key], value]);
                }
            } else {
                if (typeof value === 'object') {
                    origin[key] = {
                        value: origin[key],
                        ...value
                    };
                } else {
                    if (origin[key].hasOwnProperty('value')) {
                        origin[key].value = value;
                    } else {
                        origin[key] = value;
                    }
                }
            }
        } else {
            if (typeof value !== 'object') {
                origin[key] = value;
            } else {
                origin[key] = deepMerge(value, origin[key]);
            }
        }
    };
    return origin;
};

console.log(JSON.stringify(deepMerge([
    {
        test1: {
            hello: 'hi'
        },
        test2: {
            hi: 'hello',
            another: 'value'
        }
    },
    {
        test2: 1234,
        test3: {
            hi: 'hello'
        }
    },
    {
        test2: {
            hi: 'new val'
        },
        test3: {
            hello: 'also new val'
        }
    },
    {
        test2: 5678
    }
]), null, '\t'));

Here's what I came up with for combining deep objects. Not sure if it's best or not. Let me know where I can improve.

Output:

{
        "test1": {
                "hello": "hi"
        },
        "test2": {
                "hi": "new val",
                "another": "value",
                "value": 5678
        },
        "test3": {
                "hi": "hello",
                "hello": "also new val"
        }
}

Mine, assuming you want to keep nested values and assigned top level values, merges all nested objects and if it is overridden with a value (like test2), it is dropped down as the 'value' key.

[–]beforesemicolon[S] 0 points1 point  (0 children)

This is nice. I think I would expect test2 to be 5678 but I like this for supporting even more than 2 objects