如何基于对象属性OrderNo合并两个对象数组? -Javascript

时间:2019-04-16 03:02:44

标签: javascript arrays json object

我有2个对象数组

var arrayObj1 = [
  {
   "Plant": "Boston",
   "OrderNo": "406643",
   "Qty1": "56.1650",
   "OrderDate": null,
   "Status": null
  }
 ];

var arrayObj2 = [
  {
    "Plant": "Boston",
    "OrderNo": "406643",
    "Qty2": "22.07",
     "OrderDate": "28/11/2018",
     "Status": null
   },
   {
     "Plant": "Boston",
      "OrderNo": "526209",
      "Qty2": "21.84",
      "OrderDate": "01/03/2019",
       "Status": null
     },
     {
       "Plant": "Boston",
        "OrderNo": "526209",
        "Qty2": "65.46",
        "OrderDate": "01/03/2019",
        "Status": null
      }
    ];

我的比较参数是OrderNo,如果订单号相同,则该对象同时具有有限的Qty1和Qty2。

假设在对象的第一个数组Qty1中存在(大于0),但是对于相应的OrderNo,在对象的第二个数组中不存在Qty2,那么在新创建的对象的第三个数组中Qty2应该为0。同样,对于orderNo,如果在对象的第二个数组中存在Qty2(大于0),但对于相应的OrderNo,在对象的第一个数组中不存在Qty1,则在新创建的对象的第三个数组中Qty2应该为0。此外,我们还必须考虑到两个对象数组中的任何一个都可以完全空白数组。

我想创建一个像这样的新对象数组

var arrayObj3 = [
  {
    "Plant": "Boston",
    "OrderNo": "406643",
    "Qty1": "56.1650",// both Qty1 and Qty2 more than since both exists
    "Qty2": "22.07",// for the OrderNo 406643
     "OrderDate": "28/11/2018",
     "Status": null
   },
   {
     "Plant": "Boston",
      "OrderNo": "526209",
     "Qty1": "0",// Qty1 is 0 as it does not exist for OrderNo 526209
      "Qty2": "21.84",
      "OrderDate": "01/03/2019",
       "Status": null
     },
     {
       "Plant": "Boston",
        "OrderNo": "526209",
        "Qty1": "0",// Qty1 is 0 as it does not exist for OrderNo 526209
        "Qty2": "65.46",
        "OrderDate": "01/03/2019",
        "Status": null
      }
    ];

如何轻松实现所需的对象数组,即。 arrayObj3。有人可以为我提供Vanilla JS(没有JQuery和Lodash)的解决方案吗?

有些人误解了逻辑。在对象的第一个数组中存在Qty1(大于0),但对于相应的OrderNo,在对象的第二个数组中不存在Qty2,则在新创建的对象的第三个数组中Qty2应该为0。同样,对于orderNo,如果在对象的第二个数组中存在Qty2(大于0),但对于相应的OrderNo,在对象的第一个数组中不存在Qty1,则在新创建的对象的第三个数组中Qty2应该为0。此外,我们还必须考虑到两个对象数组中的任何一个都可以完全空白数组。

3 个答案:

答案 0 :(得分:0)

您可以使用地图:

// create a map
var setObj = {};

// add the items from the first array
arrayObj1.forEach((item) => { setObj[item.OrderNo] = item; });

// add (or merge) the items from the second array
arrayObj2.forEach((item) => { 
    if (setObj[item.OrderNo]) {
        setObj[item.OrderNo].Qty2 = item.Qty2;
    } else {
        setObj[item.OrderNo] = item;
    }
});

// extract the resulting array from the set
var arrayObj3 = Object.values(setObj);

除了在第一行使用简单的JS对象{}作为地图之外,您还可以使用 JS Map

var setObj = new Map();

如果您有很多数据,这将具有更好的性能。您需要将get()set()Map一起使用。

还有其他更快的算法,但是我认为对于您的用例来说,上面的代码简单易懂。

我的代码不能复制您的预期结果,因为您有重复的密钥,并且不清楚要复制的内容,但是您应该能够适应我所做的一切以适应此情况。

答案 1 :(得分:0)

如果我错了,请纠正我。基本上qty1的任何顺序应该来自第一个数组,qty2来自第二个数组。按照这种逻辑,解决方案是:

function mergeObjects (arr1, arr2, localKey, remoteKey) {
  
  return arr1.map(item => {
    var retObj = {...item};
    var ind = arr2.findIndex(x => item.OrderNo === x.OrderNo);
    var order = arr2[ind];
    if (order && parseFloat(retObj[localKey]) > 0 && order[remoteKey]) {
      arr2.splice(ind, 1);
      retObj[remoteKey] = order[remoteKey];
    }
    retObj[remoteKey] = retObj[remoteKey] || 0;
    return retObj;
  })
}

function createArray (arr1, arr2) {
  return [
    ...mergeObjects(arr1, arr2, 'Qty1', 'Qty2'),
    ...mergeObjects(arr2, arr1, 'Qty2', 'Qty1'),
  ]
}

var arrayObj1 = [
  {
    "Plant": "Boston",
    "OrderNo": "406643",
    "Qty1": "56.1650",
    "OrderDate": null,
    "Status": null
  }
];

var arrayObj2 = [
  {
    "Plant": "Boston",
    "OrderNo": "406643",
    "Qty2": "22.07",
    "OrderDate": "28/11/2018",
    "Status": null
  },
  {
    "Plant": "Boston",
    "OrderNo": "526209",
    "Qty2": "21.84",
    "OrderDate": "01/03/2019",
    "Status": null
  },
  {
    "Plant": "Boston",
    "OrderNo": "526209",
    "Qty2": "65.46",
    "OrderDate": "01/03/2019",
    "Status": null
  }
];
console.log(createArray(arrayObj1, arrayObj2))

答案 2 :(得分:0)

您可以使用此简单的解决方案,它使用Object.assign创建从一个对象到另一个对象的副本。这里的temp obj用于占位符,因此不会影响原始对象。

//Merged List
var mergedList = new Array();
//For each item in array2
arrayObj2.forEach(function(item){
//filter by orderNo with array1
    arrayObj1.filter(function(item2){
        if(item2.OrderNo===item.OrderNo){
            let temp ={};
            Object.assign(temp,item,item2);
            mergedList.push(temp);
        }else{
            if(!item.hasOwnProperty('Qty1')){
                let temp ={};
                Object.assign(temp,item);
                temp["Qty1"] = "";
                mergedList.push(temp);
            }
           if(!item.hasOwnProperty('Qty2')){
                let temp ={};
                Object.assign(temp,item);
                temp["Qty2"] = "";
                mergedList.push(temp);
            }
        }
    });
});

JS小提琴 https://jsfiddle.net/ejqn8c6b/1/