Normally, in node. js, we can merge two objects with underscore's extend or lodash merge, but how do we deal with complex objects like the one below?
For example I have the following two object:
var obj1 = { "name": "MyName", "status": 0, "profile": {"Sex": "M", "IsActive": true}, "Strarr": ["one", "Three"], "Objarray": [ { "id": 1, "email": "[email protected]", "IsActive": True }, { "id": 2, "email": "[email protected]", "IsActive": false } ]};var obj2 = { "name": " MyName ", " status ": 1, " Newfield ": 1, " profile ": {" IsActive ": false, " City ":" New York "}, " Strarr ": [" "], " Objarray ": [ { " id ": 1, " IsActive ": false }, { " id ": 2, "Email": "[email protected]" }, { "id": 3, "email": "[email protected]", "IsActive": True } ]};
You want the results of the merge to output as follows:
{name: ' myname ', status:1, profile : {sex: ' m ', Isactive:false, City: ' New York '}, strarr: [' One ', ' three ', ' Objarray: ' [ {id:1, email: ' [email protected] ', isactive:false}, {id:2, email: ' [email Protec Ted] ', Isactive:false}, {id:3, email: ' [email protected] ', isactive:true}],newfield:1}
By underscore or lodash existing methods we can not achieve the above results, it is only to write the code to achieve.
function Mergeobjs (Def, obj) {if (!obj) {return def; } else if (!def) {return obj; } for (var i in obj) {//If it an object if (obj[i]! = NULL && Obj[i].constructor = = object) {de F[i] = MERGEOBJS (Def[i], obj[i]); }//If its a array, simple values need to is joined. Object values need to is remerged. else if (obj[i]! = NULL && (Obj[i] instanceof Array) && obj[i].length > 0) {//test to see if T He first element is a object or not so we know the type of array we ' re dealing with. if (Obj[i][0].constructor = = Object) {var newobjs = []; Create an index of all the existing object IDs for quick access. There is no-the-know how many items are in the arrays. var objids = {} for (var x= 0, l= def[i].length; x < L; + +) {objids[def[i][x].id] = x; }//Now walk through the objects with the new array//If the ID exists, then merge the Objects. If the ID does not exist, push to the end of the Def Array for (var x= 0, l= obj[i].length; x < L; {var newobj = obj[i][x]; if (Objids[newobj.id]!== undefined) {def[i][x] = MERGEOBJS (def[i][x],newobj); } else {Newobjs.push (newobj); }} for (var x= 0, L = newobjs.length; x<l; x + +) {Def[i].push (newobjs[x]); }} else {for (var x=0; x < obj[i].length; + +) {var idxobj = obj[i][x]; if (Def[i].indexof (idxobj) = = =-1) {Def[i].push (idxobj); }}}} or else {def[i] = Obj[i]; }} return def;}
With a little improvement in the code above, we can automatically add the value of type number in the merge process.
function merge (Def, obj) {if (!obj) {return def; } else if (!def) {return obj; } for (var i in obj) {//If it an object if (obj[i]! = NULL && Obj[i].constructor = = object) {Def[i] = merge (Def[i], obj[i]); }//If its a array, simple values need to is joined. Object values need to is re-merged. else if (obj[i]! = NULL && (Obj[i] instanceof Array) && obj[i].length > 0) {//Test T o See if the first element is a object or not so we know the type of array we ' re dealing with. if (Obj[i][0].constructor = = Object) {var newobjs = []; Create an index of all the existing object IDs for quick access. There is no-the-know how many items are in the arrays. var objids = {} for (var x= 0, l= def[i].length; x < L; + +) {Objids [Def[i][x].id] = x; }//Now walk through the objects with the new array//If the ID exists, then merge the Objec Ts. If the ID does not exist, push to the end of the Def Array for (var x= 0, l= obj[i].length; x < L; ) {var newobj = obj[i][x]; if (Objids[newobj.id]!== undefined) {def[i][x] = merge (Def[i][x],newobj); } else {Newobjs.push (newobj); }} for (var x= 0, L = newobjs.length; x<l; x + +) {Def[i].push (newobjs[ X]); }} else {for (var x=0; x < obj[i].length; + +) { var idxobj = obj[i][x]; if (Def[i].indexof (idxobj) = = =-1) {Def[i].push (idxobj); }}}} else {if (IsNaN (Obj[i]) | | i.indexof (' _key ') >-1) {Def[i] = Obj[i]; } else{Def[i] + = Obj[i]; }}} return def;}
For example, the following two objects are available:
var data1 = {"_id": "577327c544bd90be508b46cc", "Channelid_info": [{"Channelid_key": "0", "se Condlevel_group ": [{" Secondlevel_key ":" 568cc36c44bd90625a045c60 "," Sender_group ": [ {"Sender_key": "577327C544BD90BE508B46CD", "Sender_sum": 40.0} ], "Senders_sum": 40.0}], "Channelid_sum": 40.0}], "Car_sum": 40.0};v Ar data2 = {"_id": "577327c544bd90be508b46cc", "Channelid_info": [{"Channelid_key": "0", "sec Ondlevel_group ": [{" Secondlevel_key ":" 568cc36c44bd90625a045c60 "," Sender_group ": [ {"Sender_key": "577327C544BD90BE508B46CD", "Sender_sum": 20.0}, {"Sender_key": "5710bcc7e66620fd4bc0914f", "Sender_sum": 5.0} ], "Senders_Sum ": 25.0}, {" Secondlevel_key ":" 55fbeb4744bd9090708b4567 "," Sender_group ": [ {"Sender_key": "5670f993a2f5dbf12e73b763", "Sender_sum": 10.0} ], "Senders_sum": 10.0}], "Channelid_sum": 35.0}, {"Channelid_key ":" 1 "," Secondlevel_group ": [{" Secondlevel_key ":" 568cc36c44bd90625a045c60 "," se Nder_group ": [{" Sender_key ":" 577327C544BD90BE508B46CD "," sender_sum ": 20.0 }], "Senders_sum": 20.0}], "Channelid_sum": 20.0}], "Car_sum": 55.0};
The results after merging are as follows:
{"_id": "577327c544bd90be508b46cc", "Channelid_info": [{"Channelid_key": "0", "secon Dlevel_group ": [{" Secondlevel_key ":" 568cc36c44bd90625a045c60 "," se Nder_group ": [{" Sender_key ":" 577327C544BD90BE508B46CD ", "Sender_sum": "$", {"Sender_key": "5710bcc7e66620fd4bc0914f", "Sender_sum": 5}], "Senders_sum": "$", {"Secondlevel_key": "55fbeb4744bd90 90708b4567 "," Sender_group ": [{" Sender_key ":" 5670f 993a2f5dbf12e73b763 "," Sender_sum ": 10}], "Senders_sum": "Channelid_sum": "Channelid_key": "1", "Secondlevel_group": [{"Secondlevel_key": "568cc36c44bd90625a045c60", "Sender_group": [{"Sender_key": "577327C544BD90BE508B46CD", "Sender_sum": "Senders_sum ": +}]," Channelid_sum ": +}]," Car_sum ": 95}
The above code is very useful in daily work, it is worth collecting!
How to merge two complex objects in node. js