How to Deeply Merge Two Object Values by Keys

How to deeply merge two object values by keys

You want a deep extend

$.extend(true, {}, x, y);

See the docs for jQuery.extend([deep], target, object1[, objectN])

How to merge Object values of two Objects

You can use spread operator.

Update :

if obj2 has some properties that obj1 does not have?

Initially i wrote this answer assuming the keys are indexed like 0,1 and so on but as you mentioned in comment this is not the case than you can build a array of keys and than iterate over it as

as very concisely added in comment by @Nick [...Object.keys(obj1), ...Object.keys(obj2)]

let obj1 = {1: { foo: 1 },2: { bar: 2, fooBar: 3 },3: { fooBar: 3 },};let obj2 = {1: { foo: 1, bar: 2 },2: { bar: 2 },};
let keys = [...new Set([...Object.keys(obj1),...Object.keys(obj2)])]let op = {}let merged = keys.forEach(key=>{ op[key] = { ...obj1[key], ...obj2[key] }})console.log(op)

How can I merge properties of two JavaScript objects dynamically?

ECMAScript 2018 Standard Method

You would use object spread:

let merged = {...obj1, ...obj2};

merged is now the union of obj1 and obj2. Properties in obj2 will overwrite those in obj1.

/** There's no limit to the number of objects you can merge.
* Later properties overwrite earlier properties with the same name. */
const allRules = {...obj1, ...obj2, ...obj3};

Here is also the MDN documentation for this syntax. If you're using babel you'll need the @babel/plugin-proposal-object-rest-spread plugin for it to work (This plugin is included in @babel/preset-env, in ES2018).

ECMAScript 2015 (ES6) Standard Method

/* For the case in question, you would do: */
Object.assign(obj1, obj2);

/** There's no limit to the number of objects you can merge.
* All objects get merged into the first object.
* Only the object in the first argument is mutated and returned.
* Later properties overwrite earlier properties with the same name. */
const allRules = Object.assign({}, obj1, obj2, obj3, etc);

(see MDN JavaScript Reference)


Method for ES5 and Earlier

for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }

Note that this will simply add all attributes of obj2 to obj1 which might not be what you want if you still want to use the unmodified obj1.

If you're using a framework that craps all over your prototypes then you have to get fancier with checks like hasOwnProperty, but that code will work for 99% of cases.

Example function:

/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* @param obj1
* @param obj2
* @returns obj3 a new object based on obj1 and obj2
*/
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}

Merge two arrays of objects based on nested object key and value

The following code combines the two arrays like you specified:

// Data

const variants = [{"name":"Name 1","variationValues":{"P00003":"mappedValue1"}},{"name":"Name 2","variationValues":{"P00003":"mappedValue2"}},{"name":"Name 3","variationValues":{"P00003":"mappedValue3"}}];
const variationAttributes = [{"id":"P00003","name":"Variant Name","attributes":[{"name":"Variant Name 1","description":"Variant Description 1","attribute":"mappedValue1"},{"name":"Variant Name 2","description":"Variant Description 2","attribute":"mappedValue2"},{"name":"Variant Name 3","description":"Variant Description 3","attribute":"mappedValue3"}]}];

// Solution code

console.log( getMappedVariants() );

function getMappedVariants() {
return variants.map((variant) => ({
...variant,
variationValues: mapValuesToAttributes(variant.variationValues),
}));
}

function mapValuesToAttributes(values) {
const attributes = {};
for (const id in values) attributes[id] = findAttribute(id, values[id]);
return attributes;
}

function findAttribute(id, value) {
const variation = variationAttributes.find((v) => v.id === id);
const attribute = variation.attributes.find((a) => a.attribute === value);
return attribute;
}

Merging two objects while keeping matching keys

You can get the keys of one of your objects, and map that to a new object, which merges the values for that key from both objects into one. You can then using Object.assign() to merge your array of mapped objects into a single resulting object like so:

const obj1 = { "title" : { "en-US" : "Some title" }, "text": { "en-US": "Some text" } } const obj2 = { "title" : { "de-DE" : "Some diffrent title" }, "text": { "de-DE": "Some diffrent text" } }
const merge_objs = (o1, o2) => Object.assign({}, ...Object.keys(o1).map(k => ({[k]: {...o1[k], ...o2[k]}}))); console.log(merge_objs(obj1, obj2));


Related Topics



Leave a reply



Submit