Skip to content

Instantly share code, notes, and snippets.

@iArnaud
Created March 25, 2014 09:17
Show Gist options
  • Save iArnaud/9757938 to your computer and use it in GitHub Desktop.
Save iArnaud/9757938 to your computer and use it in GitHub Desktop.
Javascript recursively copy two object literals
Source: http://stackoverflow.com/questions/20101788/why-does-jquery-extend-fail-to-recursively-copy-these-two-object-literals/20102047#20102047
$.extend is not meant to be used this way.
However you can write your own extend/merge function. Here's an example of a function that will merge every objects considered equal (based on the value of a specific key) from multiple provided arrays together.
The following merge algorithm will override primitive values and will concatenate arrays. The initial arrays and their objects aren't modified.
It's probably overkill if you only have to do this once, however it's an example on how you could implement your own encapsulated merging algorithm.
function mergeOnKey(mergeKey) {
var mergedObjectsIndex = {},
mergedObjects = [],
arrays = Array.prototype.slice.call(arguments, 1),
i = 0,
arraysLen = arrays.length,
x, arrLen, arr, obj, k,
mergeVal, mergedObjIndex,
mergedObj, mergedVal;
for (; i < arraysLen ; i++) {
arr = arrays[i];
for (x = 0, arrLen = arr.length; x < arrLen; x++) {
obj = arr[x];
mergeVal = obj[mergeKey];
mergedObjIndex = mergedObjectsIndex[mergeVal];
if (typeof mergedObjIndex === 'undefined') {
mergedObjectsIndex[mergeVal] = mergedObjects.push($.extend({}, obj)) - 1;
continue;
}
mergedObj = mergedObjects[mergedObjIndex];
for (k in obj) {
if (!obj.hasOwnProperty(k) || k === mergeKey) continue;
if (Array.isArray(mergedVal = mergedObj[k])) mergedObj[k] = mergedVal.concat(obj[k]);
else mergedObj[k] = obj[k];
}
}
}
return mergedObjects;
}
var obj1 = [
{ name: 'styles', items: ['Format', 'Font', 'FontSize'] },
{ name: 'colors', items: ['TextColor', 'BGColor'] },
{ name: 'tools', items: ['Maximize', 'ShowBlocks'] }
];
var obj2 = [
{ name: 'tools', items: ['Source'], test: 'test' }
];
var merged = mergeOnKey('name', obj1, obj2);
console.log(merged[2].items); //["Maximize", "ShowBlocks", "Source"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment