在Node.js中合并两个复杂对象方法步骤详解

来源:互联网 发布:北京美食小熊网络 编辑:程序博客网 时间:2024/05/21 15:07

通常情况下,在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

  }

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

 

来源:博客园

0 0
原创粉丝点击