Skip to content

Instantly share code, notes, and snippets.

@alvinsj
Last active September 4, 2015 08:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alvinsj/1a1b4c95b81b43e39e77 to your computer and use it in GitHub Desktop.
Save alvinsj/1a1b4c95b81b43e39e77 to your computer and use it in GitHub Desktop.
deep-assign (with weird mode)
var deepAssignFactory = function(weirdMode){
return function deepAssign(){
var objs = Array.prototype.slice.apply(arguments);
return objs.reduce(function(exObj, curObj){
if(Object.keys(curObj).length == 0) return exObj;
// merge whatever in curObj to exObj
return mergeSecondObjectToFirst(exObj, curObj)
}, {}); // objs.reduce
}
function mergeArrays(oldValue, curValue){
return !!weirdMode && oldValue.length == curValue.length ?
curValue.map(function(val, index){
return deepAssign(oldValue[index], val)
})
: oldValue.concat(curValue);
}
function mergeDifferentTypedValues(oldValue, curValue){
if( (oldValue instanceof Array) && (curValue instanceof Array) ){
return mergeArrays(oldValue, curValue);
}else if(typeof oldValue === 'object' && typeof curValue === 'object'){
return deepAssign(oldValue, curValue);
}else{ // replace on different type, or just value
return curValue;
}
}
function mergeSecondObjectToFirst(exObj, curObj){
return Object.keys(curObj).reduce(function(oldObj, key){
var oldValue = oldObj[key];
var curValue = curObj[key];
if(!!oldValue){ // key previously exists, deepAssign the values
oldObj[key] = mergeDifferentTypedValues(oldValue, curValue);
}else { // key never exists
oldObj[key] = curValue;
}
return oldObj;
}, exObj); // Object.keys(curObj).reduce
}
}
var exportable = deepAssignFactory(false);
exportable.weird = deepAssignFactory(true);
window.deepAssign = exportable;
module.exports = exportable;
// level 1: {b: 1, a: 1, c: 3}
deepAssign({b: 1},{a: 1}, {c: 3});
// level 2: {c: {a: 1, b: 2, c: 3}}
deepAssign({c: {a: 1}},{c: {b: 2}}, {c: {c: 3}});
// level n: {c: {a: {k: 1, d: 2, b: 3}}}
deepAssign({c: {a: {k: 1}}},{c: {a: {d: 2}}}, {c: {a: {b: 3}}});
// different type will be replaced by latter: {c: {a: {d: 2, b: 3}}}
deepAssign({c: 1},{c: {a: {d: 2}}}, {c: {a: {b: 3}}})
// in normal mode, array will be concat: {c: [{b: 2}, {a: 1}]}
deepAssign({c: [{b: 2}]}, {c: [{a: 1}]})
// in weird mode, deep-assign array elements again if arrays have the same size: {c: [{b: 2, a: 1}]}
deepAssign.weird({c: [{b: 2}]}, {c: [{a: 1}]})
// concat arrays if arrays have different sizes: {c: [{b: 2}, {a: 1}, {a: 2}]}
deepAssign({c: [{b: 2}]}, {c: [{a: 1}, {a: 2}]});
deepAssign.weird({c: [{b: 2}]}, {c: [{a: 1}, {a: 2}]});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment