1

I have two objects:

var one = {
  addedItems: [0, 1],
  removedItems: [8, 9],
  oneTwo: false,
  someStuff: {
    anotherArray: ['a', 'b']
  }
};

var two = {
  addedItems: [3, 4],
  removedItems: [6, 7],
  someStuff: {
    anotherArray: ['c', 'd']
  }
};

And in the end I need to merge these two objects and get something like this:

{
  addedItems: [0, 1, 3, 4],
  removedItems: [8, 9, 6, 7],
  oneTwo: false,
  someStuff: {
    anotherArray: ['a', 'b', 'c', 'd']
  }
}

The operation should be performed on objects with different structure.

What is the best way (or just possible way) to do this? Are there any methods in jQuery or underscore/lodash that allow to do this?

3
  • To clarify... if both objects have a property that is an array, you want to merge the 2 into each other... however what happens if a.foo:true and b.foo:false which one takes precedence when the values are atomic? Likewise if the values in the array contain duplicates do you want duplicates or just unique values? Commented Mar 7, 2017 at 14:21
  • The last one. For example if we have doConcatenation(one, two), the property from "two" will be the result property. Commented Mar 7, 2017 at 14:23
  • 1
    The concept is known as deep merging, and there is an excellent deepmerge library. Here is a blog (published yesterday) about it. Commented Mar 7, 2017 at 14:26

2 Answers 2

6

Did you check Lodash _.mergeWith(object, sources, customizer) method? I think the example does what you are basically expecting.

https://lodash.com/docs/4.17.15#mergeWith

var one = { addedItems: [0, 1], removedItems: [8, 9], oneTwo: false, someStuff: { anotherArray: ['a', 'b'] } },
    two = { addedItems: [3, 4], removedItems: [6, 7], someStuff: { anotherArray: ['c', 'd'] } };

// In case of arrays, concatenate them instead
function customizer(objValue, srcValue) {
  if (_.isArray(objValue)) {
    return objValue.concat(srcValue);
  }
}

var result = _.mergeWith(one, two, customizer);

Here's the working example in Fiddle

Sign up to request clarification or add additional context in comments.

Comments

1

You could generate a new object and append arrays with the items from the already inserted array.

function deepMerge(source, target) {
    Object.keys(source).forEach(function (k) {
        if (Array.isArray(source[k])) {
            if (!Array.isArray(target[k])) {
                target[k] = [];
            }          
            target[k] = target[k].concat(source[k]);
            return;
        }
        if (source[k] && typeof source[k] === 'object') {
            target[k] = target[k] || {};
            deepMerge(source[k], target[k]);
            return;
        }
        target[k] = source[k];
    });
}

var one = { addedItems: [0, 1], removedItems: [8, 9], oneTwo: false, someStuff: { anotherArray: ['a', 'b'] } },
    two = { addedItems: [3, 4], removedItems: [6, 7], someStuff: { anotherArray: ['c', 'd'] } },
    result = {};

deepMerge(one, result);
deepMerge(two, result);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.