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 相关文章推荐
使用js对select动态添加和删除OPTION示例代码
Aug 12 Javascript
js 获取input点选按钮的值的方法
Apr 14 Javascript
jQuery UI设置固定日期选择特效代码分享
Aug 27 Javascript
javascript点击按钮实现隐藏显示切换效果
Feb 03 Javascript
利用BootStrap弹出二级对话框的简单实现方法
Sep 21 Javascript
Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)
Feb 08 Javascript
解决vue-cli项目webpack打包后iconfont文件路径的问题
Sep 01 Javascript
基于JavaScript实现每日签到打卡轨迹功能
Nov 29 Javascript
VUE+Element环境搭建与安装的方法步骤
Jan 24 Javascript
vue elementui el-form rules动态验证的实例代码详解
May 23 Javascript
JavaScript命名空间模式实例详解
Jun 20 Javascript
Vue 微信端扫描二维码苹果端却只能保存图片问题(解决方法)
Jan 19 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中文乱码怎么办如何让浏览器自动识别utf-8
2014/01/15 PHP
php中cookie实现二级域名可访问操作的方法
2014/11/11 PHP
PHP之十六个魔术方法详细介绍
2016/11/01 PHP
Laravel框架实现定时发布任务的方法
2018/08/16 PHP
ThinkPHP中图片按比例切割的代码实例
2019/03/08 PHP
跟着Jquery API学Jquery之一 选择器
2010/04/07 Javascript
js网页侧边随页面滚动广告效果实现
2011/04/14 Javascript
JQuery扩展插件Validate 1 基本使用方法并打包下载
2011/09/05 Javascript
javascript学习基础笔记之DOM对象操作
2011/11/03 Javascript
用nodejs访问ActiveX对象,以操作Access数据库为例。
2011/12/15 NodeJs
ExtJS4中的requires使用方法示例介绍
2013/12/03 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
input标签内容改变的触发事件介绍
2014/06/18 Javascript
jQuery中prependTo()方法用法实例
2015/01/08 Javascript
js数组常见操作及数组与字符串相互转化实例详解
2015/11/10 Javascript
jQuery使用$.ajax进行即时验证的方法
2015/12/08 Javascript
一个字符串中出现次数最多的字符 统计这个次数【实现代码】
2016/04/29 Javascript
微信小程序页面跳转功能之从列表的item项跳转到下一个页面的方法
2017/11/27 Javascript
JavaScript的setter与getter方法
2017/11/29 Javascript
用Node提供静态文件服务的方法
2018/07/06 Javascript
微信小程序表单弹窗实例
2018/07/19 Javascript
小程序获取周围IBeacon设备的方法
2018/10/31 Javascript
JavaScript 空间坐标的使用
2020/08/19 Javascript
[01:37]全新的一集《真视界》——TI7总决赛
2017/09/21 DOTA
简单学习Python time模块
2016/04/29 Python
从源码解析Python的Flask框架中request对象的用法
2016/06/02 Python
Python连接数据库学习之DB-API详解
2017/02/07 Python
python实现五子棋小程序
2019/06/18 Python
Pytorch 解决自定义子Module .cuda() tensor失败的问题
2020/06/23 Python
python实现xml转json文件的示例代码
2020/12/30 Python
办理暂住证介绍信
2014/01/11 职场文书
项目合作意向书模板
2014/07/29 职场文书
保密工作整改报告
2014/11/06 职场文书
给朋友的道歉短信
2015/05/12 职场文书
法制教育主题班会
2015/08/13 职场文书
Grafana可视化监控系统结合SpringBoot使用
2022/04/19 Redis