1. 程式人生 > >如何在Node.js中合並兩個復雜對象

如何在Node.js中合並兩個復雜對象

node sum cond indexof 過程 我們 http str first

 通常情況下,在Node.js中我們可以通過underscore的extend或者lodash的merge來合並兩個對象,但是對於像下面這種復雜的對象,要如何來應對呢?

  例如我有以下兩個object:

技術分享
var obj1 = {
    "name" : "myname",
    "status" : 0,
    "profile": { "sex":"m", "isactive" : true},
    "strarr":["one", "three"],
    "objarray": [
    {
        "id": 1,
        "email": "[email protected]
/* */", "isactive":true }, { "id": 2, "email": "[email protected]", "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": "[email protected]
/* */" }, { "id": 3, "email": "[email protected]", "isactive" : true } ] }; 技術分享

  希望合並之後的結果輸出成下面這樣:

技術分享
{ name: ‘myname‘,
  status: 1,
  profile: { sex: ‘m‘, isactive: false, city: ‘new York‘ },
  strarr: [ ‘one‘, ‘three‘, ‘two‘ ],
  objarray: 
  [ { id: 1, email: [email protected]
/* */, isactive: false }, { id: 2, email: [email protected], isactive: false }, { id: 3, email: [email protected], 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
}
技術分享

  上述代碼在日常工作中很有用,值得收藏!

如何在Node.js中合並兩個復雜對象

相關推薦

如何在Node.js

node sum cond indexof 過程 我們 http str first  通常情況下,在Node.js中我們可以通過underscore的extend或者lodash的merge來合並兩個對象,但是對於像下面這種復雜的對象,要如何來應對呢?   例如我有以下兩

算法練習之有序鏈表, 刪除排序數組的重項,移除元素,實現strStr(),搜索插入位置

重復 按順序 function color ram remove insert substring 應該 最近在學習java,但是對於數據操作那部分還是不熟悉 因此決定找幾個簡單的算法寫,用php和java分別實現 1.合並兩個有序鏈表 將兩個有序鏈表合並為一個新的有

C語言集合(L,L1) 將L1不在L的元素插入到L線性表

時間復雜度 itl main 所有 bsp 插入 復雜 i++ ins void main(){ Sqlist L,L1; InitList(&L); InitList(&L1); ListInsert(&L, 1, 2); ListIns

leetcode鏈表--8、merge-two-sorted-list(按順序已經排好序的鏈表)

截圖 技術 鏈表 兩個 16px sizeof 一個 運行結果截圖 div 題目描述 Merge two sorted linked lists and return it as a new list. The new list should be made by sp

排序的鏈表

list tno 測試用例 大小 listnode 同時 合並 head 代碼 錯誤代碼: 最後兩個if語句的目的是,最後一次叠代,兩個鏈表中剩下的直接連接最後一次比較的數值,同時也是叠代停止的標誌。雖然大if語句中比較大小得到的Node是正確的值,但每次叠代只要pHead

《劍指Offer》題目:排序的鏈表

合成 sorted 合並 邊界情況 logs pub st2 next null 題目描述:輸入兩個單調遞增的鏈表list1,list2,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。 題目分析: 1.對於鏈表題目,首先考慮邊界情況,即鏈表為空的情況,

有序數組為一個新的有序數組

int tro pre pri ack ati 數組 data- string 題目:有兩個有序數組a,b,現須要將其合並成一個新的有序數組。 簡單的思路就是先放到一個新的數組中,再排序。可是這種沒體現不論什麽算法,這裏考的不是高速排序等排序算法。關鍵應該是怎樣利

merge-sorted-array——有序數組

nts from -a else array integer ber sum initial Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may

17.排序的鏈表

pac .net -a enter spa span tracking data 空指針 當代碼試圖訪問空指針指向的內存時程序就會崩潰,從而導致魯棒性問題。所以要對空鏈表單獨處理。 ListNode* Merge(ListNode* pHead1, L

leetcode算法題2: 二叉樹。遞歸,如何切入保持清醒?

leetcode算法題2: 合並兩個二叉樹。遞歸 如何切入並保持清醒? /* Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees

逆轉交替鏈表

包含 con 技術分享 article 進行 log 輸入 帶來 方式 一、問題描寫敘述 鏈表A和B A: 1->2->3->4 B: a->b->c->d 請逆轉交替合並兩個鏈表,演示樣例結果例如以下: 4->

排序鏈表

算法 desc 有一個 合並 solution 我們 describe ext while 題目描述 輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。 思路:非遞歸 class Solution { publi

PHP 二維數組 array_map 和 array_walk 的區別

blog merge 返回 spa ret use walk urn 結果 array_map array_walk 函數介紹 為數組的每個元素應用回調函數 使用用戶自定義函數對數組中的每個元素做回調處理 版本限制 (PHP 4 >= 4.

算法總結之 有序的單鏈表

插入 一個 大小 spa 下一步 則無 算法總結 做出 頭節點 給定兩個有序單鏈表的頭節點head1 和 head2 ,請合並兩個有序鏈表,合並後的鏈表依然有序,並返回合並後鏈表的頭節點 假設兩個鏈表長度為M和N 直接給出時間復雜度為(M+N) 額外空間復雜度O(1

劍指offer17排序的鏈表

info tar sq01 www pci ohs tee fga ref Tv運遠廈7V籽4姓62http://shequ.docin.com/vkih86746 201m蚜疽6qg壤笛http://tushu.docin.com/fhqrw5685 8lUo孜拇迸s

劍指offer十六之排序的鏈表

gif 虛線 tno 合並鏈表 -- class sed net isp 一、題目   輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。 二、思路   註:鏈表1和鏈表2是兩個遞增排序的鏈表,合並這兩個鏈表得到升序鏈表為鏈表3.

劍指offer-排序的鏈表

tno ide next val spa blog view offer 註意 從小的開始作為頭結點,然後比較選擇較小的進行鏈接 需要註意頭結點確定的時候就要保存下來,因為後面會一直變化往後鏈接新元素 /* struct ListNode { int

有序單鏈表

理解 你在 ati write 編程 ems index all rebuild 在歸並排序中,對順序存儲的且為升序的兩個列表a和b進行合並,合並後的列表為c,實現如下: 1 /** 2 * Merge two sorted src array a[] and b[

面試題----有序數組

合並 printf 面試 有序數組 color merge set ++ style #include<stdio.h> #include<string.h> #include<stdlib.h> void merge(int a[]

【JQuery】使用JQuery json

table true ble nbsp 參考 jquer log con merge 一,保存object1和2合並後產生新對象,若2中有與1相同的key,默認2將會覆蓋1的值 1 var object = $.extend({}, object1, obj