UDN-企业互联网技术人气社区

板块导航

浏览  : 608
回复  : 2

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

[复制链接]
泡泡兔的头像 楼主
发表于 2017-1-4 15:28:29 | 显示全部楼层 |阅读模式
  通常情况下,在Node.js中我们可以通过 underscore 的 extend 或者 lodash 的 merge 来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢?

  例如我有以下两个object:
  1. var obj1 = {
  2.     "name" : "myname",
  3.     "status" : 0,
  4.     "profile": { "sex":"m", "isactive" : true},
  5.     "strarr":["one", "three"],
  6.     "objarray": [
  7.     {
  8.         "id": 1,
  9.         "email": "a1@me.com",
  10.         "isactive":true
  11.     },
  12.     {
  13.         "id": 2,
  14.         "email": "a2@me.com",
  15.         "isactive":false
  16.     }
  17.     ]
  18. };

  19. var obj2 = {
  20.     "name" : "myname",
  21.     "status" : 1,
  22.     "newfield": 1,
  23.     "profile": { "isactive" : false,  "city": "new York"},
  24.     "strarr":["two"],
  25.     "objarray": [
  26.     {
  27.         "id": 1,
  28.         "isactive":false
  29.     },
  30.     {
  31.         "id": 2,
  32.         "email": "a2modified@me.com"
  33.     },
  34.     {
  35.         "id": 3,
  36.         "email": "a3new@me.com",
  37.         "isactive" : true
  38.     }
  39.     ]
  40. };
复制代码

  希望合并之后的结果输出成下面这样:
  1. { name: 'myname',
  2.   status: 1,
  3.   profile: { sex: 'm', isactive: false, city: 'new York' },
  4.   strarr: [ 'one', 'three', 'two' ],
  5.   objarray:
  6.   [ { id: 1, email: 'a1@me.com', isactive: false },
  7.    { id: 2, email: 'a2modified@me.com', isactive: false },
  8.    { id: 3, email: 'a3new@me.com', isactive: true } ],
  9. newfield: 1 }
复制代码

  通过 underscore 或者 lodash 现有的方法我们无法实现上述结果,那只能自己写代码来实现了。
  1. function mergeObjs(def, obj) {
  2.   if (!obj) {
  3.     return def;
  4.   } else if (!def) {
  5.     return obj;
  6.   }

  7.   for (var i in obj) {
  8.     // if its an object
  9.     if (obj[i] != null && obj[i].constructor == Object)
  10.     {
  11.       def[i] = mergeObjs(def[i], obj[i]);
  12.     }
  13.     // if its an array, simple values need to be joined.  Object values need to be remerged.
  14.     else if(obj[i] != null && (obj[i] instanceof Array) && obj[i].length > 0)
  15.     {
  16.       // test to see if the first element is an object or not so we know the type of array we're dealing with.
  17.       if(obj[i][0].constructor == Object)
  18.       {
  19.         var newobjs = [];
  20.         // 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.
  21.         var objids = {}
  22.         for(var x= 0, l= def[i].length ; x < l; x++ )
  23.         {
  24.           objids[def[i][x].id] = x;
  25.         }

  26.         // now walk through the objects in the new array
  27.         // if the ID exists, then merge the objects.
  28.         // if the ID does not exist, push to the end of the def array
  29.         for(var x= 0, l= obj[i].length; x < l; x++)
  30.         {
  31.           var newobj = obj[i][x];
  32.           if(objids[newobj.id] !== undefined)
  33.           {
  34.             def[i][x] = mergeObjs(def[i][x],newobj);
  35.           }
  36.           else {
  37.             newobjs.push(newobj);
  38.           }
  39.         }

  40.         for(var x= 0, l = newobjs.length; x<l; x++) {
  41.           def[i].push(newobjs[x]);
  42.         }
  43.       }
  44.       else {
  45.         for(var x=0; x < obj[i].length; x++)
  46.         {
  47.           var idxObj = obj[i][x];
  48.           if(def[i].indexOf(idxObj) === -1) {
  49.              def[i].push(idxObj);
  50.           }
  51.         }
  52.       }
  53.     }
  54.     else
  55.     {
  56.       def[i] = obj[i];
  57.     }
  58.   }
  59.   return def;}
复制代码

  将上述代码稍作改进,我们可以实现在合并过程中将Number类型的值自动相加。
  1. function merge(def, obj) {
  2.     if (!obj) {
  3.         return def;
  4.     }
  5.     else if (!def) {
  6.         return obj;
  7.     }

  8.     for (var i in obj) {
  9.         // if its an object
  10.         if (obj[i] != null && obj[i].constructor == Object)
  11.         {
  12.             def[i] = merge(def[i], obj[i]);
  13.         }
  14.         // if its an array, simple values need to be joined.  Object values need to be re-merged.
  15.         else if(obj[i] != null && (obj[i] instanceof Array) && obj[i].length > 0)
  16.         {
  17.             // test to see if the first element is an object or not so we know the type of array we're dealing with.
  18.             if(obj[i][0].constructor == Object)
  19.             {
  20.                 var newobjs = [];
  21.                 // 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.
  22.                 var objids = {}
  23.                 for(var x= 0, l= def[i].length ; x < l; x++ )
  24.                 {
  25.                     objids[def[i][x].id] = x;
  26.                 }

  27.                 // now walk through the objects in the new array
  28.                 // if the ID exists, then merge the objects.
  29.                 // if the ID does not exist, push to the end of the def array
  30.                 for(var x= 0, l= obj[i].length; x < l; x++)
  31.                 {
  32.                     var newobj = obj[i][x];
  33.                     if(objids[newobj.id] !== undefined)
  34.                     {
  35.                         def[i][x] = merge(def[i][x],newobj);
  36.                     }
  37.                     else {
  38.                         newobjs.push(newobj);
  39.                     }
  40.                 }

  41.                 for(var x= 0, l = newobjs.length; x<l; x++) {
  42.                     def[i].push(newobjs[x]);
  43.                 }
  44.             }
  45.             else {
  46.                 for(var x=0; x < obj[i].length; x++)
  47.                 {
  48.                     var idxObj = obj[i][x];
  49.                     if(def[i].indexOf(idxObj) === -1) {
  50.                         def[i].push(idxObj);
  51.                     }
  52.                 }
  53.             }
  54.         }
  55.         else
  56.         {
  57.             if (isNaN(obj[i]) || i.indexOf('_key') > -1){
  58.                 def[i] = obj[i];
  59.             }
  60.             else{
  61.                 def[i] += obj[i];
  62.             }
  63.         }
  64.     }
  65.     return def;
  66. }
复制代码

  例如有以下两个对象:
  1. var data1 = {
  2.     "_id" : "577327c544bd90be508b46cc",
  3.     "channelId_info" : [
  4.     {
  5.         "channelId_key" : "0",
  6.         "secondLevel_group" : [
  7.         {
  8.             "secondLevel_key" : "568cc36c44bd90625a045c60",
  9.             "sender_group" : [
  10.             {
  11.                 "sender_key" : "577327c544bd90be508b46cd",
  12.                 "sender_sum" : 40.0
  13.             }
  14.             ],
  15.             "senders_sum" : 40.0
  16.         }
  17.         ],
  18.         "channelId_sum" : 40.0
  19.     }
  20.     ],
  21.     "car_sum" : 40.0
  22. };

  23. var data2 = {
  24.     "_id" : "577327c544bd90be508b46cc",
  25.     "channelId_info" : [
  26.     {
  27.         "channelId_key" : "0",
  28.         "secondLevel_group" : [
  29.         {
  30.             "secondLevel_key" : "568cc36c44bd90625a045c60",
  31.             "sender_group" : [
  32.             {
  33.                 "sender_key" : "577327c544bd90be508b46cd",
  34.                 "sender_sum" : 20.0
  35.             },
  36.             {
  37.                 "sender_key" : "5710bcc7e66620fd4bc0914f",
  38.                 "sender_sum" : 5.0
  39.             }
  40.             ],
  41.             "senders_sum" : 25.0
  42.         },
  43.         {
  44.             "secondLevel_key" : "55fbeb4744bd9090708b4567",
  45.             "sender_group" : [
  46.             {
  47.                 "sender_key" : "5670f993a2f5dbf12e73b763",
  48.                 "sender_sum" : 10.0
  49.             }
  50.             ],
  51.             "senders_sum" : 10.0
  52.         }
  53.         ],
  54.         "channelId_sum" : 35.0
  55.     },
  56.     {
  57.         "channelId_key" : "1",
  58.         "secondLevel_group" : [
  59.         {
  60.             "secondLevel_key" : "568cc36c44bd90625a045c60",
  61.             "sender_group" : [
  62.             {
  63.                 "sender_key" : "577327c544bd90be508b46cd",
  64.                 "sender_sum" : 20.0
  65.             }
  66.             ],
  67.             "senders_sum" : 20.0
  68.         }
  69.         ],
  70.         "channelId_sum" : 20.0
  71.     }
  72.     ],
  73.     "car_sum" : 55.0
  74. };
复制代码

  合并之后的结果如下:
  1. {
  2.     "_id": "577327c544bd90be508b46cc",
  3.     "channelId_info": [
  4.         {
  5.             "channelId_key": "0",
  6.             "secondLevel_group": [
  7.                 {
  8.                     "secondLevel_key": "568cc36c44bd90625a045c60",
  9.                     "sender_group": [
  10.                         {
  11.                             "sender_key": "577327c544bd90be508b46cd",
  12.                             "sender_sum": 60
  13.                         },
  14.                         {
  15.                             "sender_key": "5710bcc7e66620fd4bc0914f",
  16.                             "sender_sum": 5
  17.                         }
  18.                     ],
  19.                     "senders_sum": 65
  20.                 },
  21.                 {
  22.                     "secondLevel_key": "55fbeb4744bd9090708b4567",
  23.                     "sender_group": [
  24.                         {
  25.                             "sender_key": "5670f993a2f5dbf12e73b763",
  26.                             "sender_sum": 10
  27.                         }
  28.                     ],
  29.                     "senders_sum": 10
  30.                 }
  31.             ],
  32.             "channelId_sum": 75
  33.         },
  34.         {
  35.             "channelId_key": "1",
  36.             "secondLevel_group": [
  37.                 {
  38.                     "secondLevel_key": "568cc36c44bd90625a045c60",
  39.                     "sender_group": [
  40.                         {
  41.                             "sender_key": "577327c544bd90be508b46cd",
  42.                             "sender_sum": 20
  43.                         }
  44.                     ],
  45.                     "senders_sum": 20
  46.                 }
  47.             ],
  48.             "channelId_sum": 20
  49.         }
  50.     ],
  51.     "car_sum": 95
  52. }
复制代码

相关帖子

发表于 2017-1-4 15:28:59 | 显示全部楼层
jq现在应该算是最火的js框架类了吧?确实很强大extjs基于Yahoo UI的扩展,界面布局和效果方面很给力,但就是有点复杂
使用道具 举报

回复

发表于 2017-1-4 15:29:00 | 显示全部楼层
js是要逆天的节奏js虽然不错,但是天生也是有缺陷,局限性。。。
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部