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创建表格(自动增加表格)代码分享
Dec 25 Javascript
Javascript连接多个数组不用concat来解决
Mar 24 Javascript
IONIC自定义subheader的最佳解决方案
Sep 22 Javascript
十大热门的JavaScript框架和库
Mar 21 Javascript
bootstrap警告框示例代码分享
May 17 Javascript
解决Vue编译时写在style中的路径问题
Sep 21 Javascript
es6新特性之 class 基本用法解析
May 05 Javascript
JS实现生成由字母与数字组合的随机字符串功能详解
May 25 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
Oct 11 Javascript
详解Vue、element-ui、axios实现省市区三级联动
May 07 Javascript
js实现轮播图效果 纯js实现图片自动切换
Aug 09 Javascript
vue自定义树状结构图的实现方法
Oct 18 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
PHP curl_setopt()函数实例代码与参数分析
2011/06/02 PHP
关于zend studio 出现乱码问题的总结
2013/06/23 PHP
PHP输出一个等腰三角形的方法
2015/05/12 PHP
PHP7 新增功能
2021/03/09 PHP
greybox——不开新窗口看新的网页
2007/02/20 Javascript
javascript显示隐藏层比较不错的方法分析
2008/09/30 Javascript
用javascript getComputedStyle获取和设置style的原理
2008/10/10 Javascript
JavaScript 密码强度判断代码
2009/09/05 Javascript
高性能web开发 如何加载JS,JS应该放在什么位置?
2010/05/14 Javascript
如何让页面在打开时自动刷新一次让图片全部显示
2012/12/17 Javascript
jQuery图片轮播的具体实现
2013/09/11 Javascript
js去除空格的12种实用方法
2013/11/08 Javascript
使用forever管理nodejs应用教程
2014/06/03 NodeJs
angular使用post、get向后台传参的问题实例
2017/05/27 Javascript
webpack学习教程之publicPath路径问题详解
2017/06/17 Javascript
限时抢购-倒计时的完整实例(分享)
2017/09/17 Javascript
什么时候不能在 Node.js 中使用 Lock Files
2019/06/24 Javascript
vuex state中的数组变化监听实例
2019/11/06 Javascript
[03:40]DOTA2抗疫特别篇《英雄年代》
2020/02/28 DOTA
python如何压缩新文件到已有ZIP文件
2018/03/14 Python
Python selenium抓取微博内容的示例代码
2018/05/17 Python
Python之list对应元素求和的方法
2018/06/28 Python
Django框架安装方法图文详解
2019/11/04 Python
python如果快速判断数字奇数偶数
2019/11/13 Python
Django User 模块之 AbstractUser 扩展详解
2020/03/11 Python
如何通过python计算圆周率PI
2020/11/11 Python
CSS3实现酷炫的3D旋转透视效果
2019/11/21 HTML / CSS
HTML5 manifest离线缓存的示例代码
2018/08/08 HTML / CSS
西班牙在线宠物商店:zooplus.es
2017/02/24 全球购物
Chinti & Parker官网:奢华羊绒女装和创新针织设计
2021/01/01 全球购物
Jones Bootmaker官网:优质靴子和鞋子在线
2020/11/30 全球购物
七一党建活动方案
2014/01/28 职场文书
信用社竞聘演讲稿
2014/05/16 职场文书
个人批评与自我批评材料
2014/10/17 职场文书
初中教师个人总结
2015/02/10 职场文书
2015年师德师风自我评价范文
2015/03/05 职场文书