Node.js中如何合并兩個(gè)復(fù)雜對(duì)象詳解
前言
相信大家都知道在通常情況下,在Node.js中我們可以通過(guò)underscore的extend或者lodash的merge來(lái)合并兩個(gè)對(duì)象,但是對(duì)于像下面這種復(fù)雜的對(duì)象,要如何來(lái)應(yīng)對(duì)呢?下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
Node.js合并兩個(gè)復(fù)雜對(duì)象
例如我有以下兩個(gè)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
}
]
};
希望合并之后的結(jié)果輸出成下面這樣:
{ 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 }
通過(guò)underscore或者lodash現(xiàn)有的方法我們無(wú)法實(shí)現(xiàn)上述結(jié)果,那只能自己寫(xiě)代碼來(lái)實(shí)現(xiàn)了。
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;}
將上述代碼稍作改進(jìn),我們可以實(shí)現(xiàn)在合并過(guò)程中將Number類(lèi)型的值自動(dòng)相加。
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;
}
例如有以下兩個(gè)對(duì)象:
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
};
合并之后的結(jié)果如下:
{
"_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
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,文中提到的上述代碼在日常工作中很有用,值得大家收藏!希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助。
相關(guān)文章
Node.js16.15.1的一個(gè)報(bào)錯(cuò)以及解決方案分享
這篇文章主要給大家介紹了關(guān)于Node.js16.15.1的一個(gè)報(bào)錯(cuò)以及解決方案的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-12-12
node.js 使用ejs模板引擎時(shí)后綴換成.html
本文給大家分享一個(gè)nodejs的小技巧,將ejs模板引擎的模板后綴改成.html的使用方法,非常的簡(jiǎn)單實(shí)用,這里推薦給大家。2015-04-04
淺談Express.js解析Post數(shù)據(jù)類(lèi)型的正確姿勢(shì)
這篇文章主要介紹了Express.js解析Post數(shù)據(jù)類(lèi)型的正確姿勢(shì),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
nodejs結(jié)合Socket.IO實(shí)現(xiàn)的即時(shí)通訊功能詳解
這篇文章主要介紹了nodejs結(jié)合Socket.IO實(shí)現(xiàn)的即時(shí)通訊功能,結(jié)合實(shí)例形式詳細(xì)分析了nodejs結(jié)合Socket.IO實(shí)現(xiàn)即時(shí)通訊的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-01-01
nodejs同步調(diào)用獲取mysql數(shù)據(jù)時(shí)遇到的大坑
今天小編就為大家分享一篇關(guān)于nodejs同步調(diào)用獲取mysql數(shù)據(jù)時(shí)遇到的大坑,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
node.js使用stream模塊實(shí)現(xiàn)自定義流示例
這篇文章主要介紹了node.js使用stream模塊實(shí)現(xiàn)自定義流,結(jié)合實(shí)例形式詳細(xì)分析了node.js基于stream模塊實(shí)現(xiàn)自定義的可讀流、可寫(xiě)流、可讀寫(xiě)流等相關(guān)操作技巧,需要的朋友可以參考下2020-02-02
在Linux系統(tǒng)中搭建Node.js開(kāi)發(fā)環(huán)境的簡(jiǎn)單步驟講解
這篇文章主要介紹了在Linux系統(tǒng)中搭建Node.js開(kāi)發(fā)環(huán)境的步驟,Node使得JavaScript程序可以在本地操作系統(tǒng)環(huán)境中解釋運(yùn)行,需要的朋友可以參考下2016-01-01
Node.js console控制臺(tái)簡(jiǎn)單用法分析
這篇文章主要介紹了Node.js console控制臺(tái)簡(jiǎn)單用法,結(jié)合實(shí)例形式分析了nodejs console控制臺(tái)功能、常見(jiàn)函數(shù)與簡(jiǎn)單使用技巧,需要的朋友可以參考下2019-01-01

