• 如何在Node.js中合并两个复杂对象


      通常情况下,在Node.js中我们可以通过underscoreextend或者lodashmerge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢?

      例如我有以下两个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
    }

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

  • 相关阅读:
    单步调试理解webpack里通过require加载nodejs原生模块实现原理
    webpack打包过程如何调试?
    django-数据库之连接数据库
    django-模板之include标签(十五)
    django-模板之静态文件加载(十四)
    django-模板之过滤器Add(十三)
    django-模板之with标签(十二)
    django-模板之for empty(十一)
    django-模板之if语句(九)
    django-模板之自动转义autoescape(八)
  • 原文地址:https://www.cnblogs.com/jaxu/p/6221301.html
Copyright © 2020-2023  润新知