首页 > 代码库 > 如何在Node.js中合并两个复杂对象

如何在Node.js中合并两个复杂对象

通常情况下,在Node.js开发中我们可以通过 underscore  extend 或者 lodash  merge 来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢?

例如我有以下两个object

var obj1 = {

"name" : "myname",

"status" : 0,

"profile": { "sex":"m", "isactive" : true},

"strarr":["one", "three"],

"objarray": [

{

"id": 1,

"email": "a1@me.com",

"isactive":true

},

{

"id": 2,

"email": "a2@me.com",

"isactive":false

}

]

};

var obj2 = {

"name" : "myname",

"status" : 1,

"newfield": 1,

"profile": { "isactive" : false, "city": "new York"},

"strarr":["two"],

"objarray": [

{

"id": 1,

"isactive":false

},

{

"id": 2,

"email": "a2modified@me.com"

},

{

"id": 3,

"email": "a3new@me.com",

"isactive" : true

}

]

};

希望合并之后的结果输出成下面这样:

name: ’myname’,

status: 1,

profile: { sex: ’m’, isactive: false, city: ’new York’ },

strarr: [ ’one’, ’three’, ’two’ ],

objarray:

[ { id: 1, email: ’a1@me.com’, isactive: false },

id: 2, email: ’a2modified@me.com’, isactive: false },

id: 3, email: ’a3new@me.com’, isactive: true } ],newfield: 1 }

通过 underscore 或者 lodash 现有的方法我们无法实现上述结果,那只能自己写代码来实现了。

function mergeObjs(defobj) {

if (!obj) {

return def;

else if (!def) {

return obj;

}

for (var i in obj) {

// if its an object

if (obj[i] != null && obj[i].constructor == Object)

{

def[i] = mergeObjs(def[i], obj[i]);

}

// if its an array, simple values need to be joined. Object values need to be remerged.

else if(obj[i] != null && (obj[i] instanceof Array) && obj[i].length > 0)

{

// test to see if the first element is an 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 way to know how many items will be in the arrays.

var objids = {}

for(var x= 0, l= def[i].length ; x < l; x++ )

{

objids[def[i][x].id] = x;

}

// now walk through the objects in 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; x++)

{

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; x++)

{

var idxObj = obj[i][x];

if(def[i].indexOf(idxObj) === -1) {

def[i].push(idxObj);

}

}

}

}

else

{

def[i] = obj[i];

}

}

return def;}

将上述代码稍作改进,我们可以实现在合并过程中将Number类型的值自动相加。

function merge(defobj) {

if (!obj) {

return def;

}

else if (!def) {

return obj;

}

for (var i in obj) {

// if its an object

if (obj[i] != null && obj[i].constructor == Object)

{

def[i] = merge(def[i], obj[i]);

}

// if its an array, simple values need to be joined. Object values need to be re-merged.

else if(obj[i] != null && (obj[i] instanceof Array) && obj[i].length > 0)

{

// test to see if the first element is an 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 way to know how many items will be in the arrays.

var objids = {}

for(var x= 0, l= def[i].length ; x < l; x++ )

{

objids[def[i][x].id] = x;

}

// now walk through the objects in 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; x++)

{

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; x++)

{

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;

}

例如有以下两个对象:

var data1 = {

"_id" : "577327c544bd90be508b46cc",

"channelId_info" : [

{

"channelId_key" : "0",

"secondLevel_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

};

var data2 = {

"_id" : "577327c544bd90be508b46cc",

"channelId_info" : [

{

"channelId_key" : "0",

"secondLevel_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",

"sender_group" : [

{

"sender_key" : "577327c544bd90be508b46cd",

"sender_sum" : 20.0

}

],

"senders_sum" : 20.0

}

],

"channelId_sum" : 20.0

}

],

"car_sum" : 55.0

};

合并之后的结果如下:

{

"_id": "577327c544bd90be508b46cc",

"channelId_info": [

{

"channelId_key": "0",

"secondLevel_group": [

{

"secondLevel_key": "568cc36c44bd90625a045c60",

"sender_group": [

{

"sender_key": "577327c544bd90be508b46cd",

"sender_sum": 60

},

{

"sender_key": "5710bcc7e66620fd4bc0914f",

"sender_sum": 5

}

],

"senders_sum": 65

},

{

"secondLevel_key": "55fbeb4744bd9090708b4567",

"sender_group": [

{

"sender_key": "5670f993a2f5dbf12e73b763",

"sender_sum": 10

}

],

"senders_sum": 10

}

],

"channelId_sum": 75

},

{

"channelId_key": "1",

"secondLevel_group": [

{

"secondLevel_key": "568cc36c44bd90625a045c60",

"sender_group": [

{

"sender_key": "577327c544bd90be508b46cd",

"sender_sum": 20

}

],

"senders_sum": 20

}

],

"channelId_sum": 20

}

],

"car_sum": 95

}

上述代码在日常工作中很有用,值得收藏!

 

来源:博客园

如何在Node.js中合并两个复杂对象