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


Posted in Javascript onDecember 31, 2016

前言

相信大家都知道在通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢?下面来一起学习学习吧。

Node.js合并两个复杂对象

例如我有以下两个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(def, obj) {
 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(def, obj) {
 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
}

总结

以上就是这篇文章的全部内容了,文中提到的上述代码在日常工作中很有用,值得大家收藏!希望本文的内容对大家的学习或者工作能带来一定的帮助。

Javascript 相关文章推荐
基于jquery的回到页面顶部按钮
Jun 27 Javascript
jQuery中:has选择器用法实例
Dec 30 Javascript
JavaScript数组合并的多种方法
May 22 Javascript
JavaScript闭包实例详解
Jun 03 Javascript
JavaScript将DOM事件处理程序封装为event.js 出现的低级错误问题
Aug 03 Javascript
浅谈JS继承_寄生式继承 &amp; 寄生组合式继承
Aug 16 Javascript
Javascript之面向对象--封装
Dec 02 Javascript
js判断PC端与移动端跳转
Dec 24 Javascript
MUI 上拉刷新/下拉加载功能实例代码
Apr 13 Javascript
seajs模块压缩问题与解决方法实例分析
Oct 10 Javascript
浅谈js中的bind
Mar 18 Javascript
使用react-virtualized实现图片动态高度长列表的问题
May 28 Javascript
javascript 闭包详解及简单实例应用
Dec 31 #Javascript
深入理解Angularjs中的$resource服务
Dec 31 #Javascript
BootStrap Fileinput的使用教程
Dec 30 #Javascript
BootStrap Fileinput初始化时的一些参数
Dec 30 #Javascript
bootstrapValidator表单验证插件学习
Dec 30 #Javascript
JS实现类似百叶窗下拉菜单效果
Dec 30 #Javascript
BootStrap实现轮播图效果(收藏)
Dec 30 #Javascript
You might like
Apache, PHP在Windows 9x/NT下的安装与配置 (一)
2006/10/09 PHP
laravel解决迁移文件一次删除创建字段报错的问题
2019/10/24 PHP
php设计模式之观察者模式实例详解【星际争霸游戏案例】
2020/03/30 PHP
KindEditor在php环境下上传图片功能集成的方法示例
2020/07/20 PHP
关于文本限制字数的js代码
2007/04/02 Javascript
Javascript 读书笔记索引贴
2010/01/11 Javascript
ExtJS 下拉多选框lovcombo
2010/05/19 Javascript
js去字符串前后空格的实现方法
2016/02/26 Javascript
浅谈jquery选择器 :first与:first-child的区别
2016/11/20 Javascript
react性能优化达到最大化的方法 immutable.js使用的必要性
2017/03/09 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
微信小程序报错:this.setData is not a function的解决办法
2017/09/27 Javascript
jquery实现回车键触发事件(实例讲解)
2017/11/21 jQuery
Vue多组件仓库开发与发布详解
2019/02/28 Javascript
Element Tooltip 文字提示的使用示例
2020/07/26 Javascript
[03:12]完美世界DOTA2联赛PWL DAY9集锦
2020/11/10 DOTA
[01:20:38]完美世界DOTA2联赛 GXR vs IO 第一场 11.07
2020/11/09 DOTA
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
2016/10/12 Python
Python编程实现删除VC临时文件及Debug目录的方法
2017/03/22 Python
浅析python中的迭代与迭代对象
2018/10/08 Python
Python中新式类与经典类的区别详析
2019/07/10 Python
Python读取图像并显示灰度图的实现
2020/12/01 Python
使用HTML5和CSS3表单验证功能
2017/05/05 HTML / CSS
美国知名的家庭连锁百货商店:Boscov’s
2017/07/27 全球购物
汇集了世界上最好的天然和有机美容产品:LoveLula
2018/02/05 全球购物
国际性能运动服装品牌:Dare 2b
2018/07/27 全球购物
母亲追悼会答谢词
2014/01/27 职场文书
党校培训自我鉴定范文
2014/03/20 职场文书
关于热爱祖国的演讲稿
2014/05/04 职场文书
一年级数学下册复习计划
2015/01/17 职场文书
小学国庆节活动总结
2015/03/23 职场文书
千与千寻观后感
2015/06/04 职场文书
信用卡工作证明范本
2015/06/19 职场文书
先进基层党组织主要事迹材料
2015/11/03 职场文书
小学体育课教学反思
2016/02/16 职场文书
创业计划书之旅游网站
2019/09/06 职场文书