简体   繁体   中英

How to merge two arrays of objects based on a object attribute OrderNo? - Javascript

I have 2 arrays of objects

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
      }
    ];

My comparing parameter is OrderNo, if order number is same then that object has both finite Qty1 and Qty2.

Suppose in first array of object Qty1 exists (greater than 0) but for corresponding OrderNo no Qty2 exists in the 2nd array of object then Qty2 should be 0 in the newly created 3rd array of object. SImilarly for a orderNo, if Qty2 exists (greater than 0) in 2nd array of object but for corresponding OrderNo no Qty1 exists in 1st array of object then Qty2 should be 0 in the newly created 3rd array of object. Also we have to consider that any one of the two array of objects can completely blank array.

I want to create a new array of object like this

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
      }
    ];

How can I easily achieve my desired array of object ie. arrayObj3. Can someone provide me a solution in Vanilla JS (without JQuery and Lodash)?

Some people are misunderstanding the logic. In first array of object Qty1 exists (greater than 0) but for corresponding OrderNo no Qty2 exists in the 2nd array of object then Qty2 should be 0 in the newly created 3rd array of object. SImilarly for a orderNo, if Qty2 exists (greater than 0) in 2nd array of object but for corresponding OrderNo no Qty1 exists in 1st array of object then Qty2 should be 0 in the newly created 3rd array of object. Also we have to consider that any one of the two array of objects can completely blank array.

You can use a map:

// 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);

Rather than use a simple JS object {} as the map on the first line, you can also use the JS Map :

var setObj = new Map();

This has better performance if you have a lot of data. You need to use get() and set() with Map .

There are other algorithms which are faster, but I think that for your use case, the above code is simple and easy to understand.

My code does not replicate your expected result, because you have duplicate keys and it is not clear what you intend for duplicates, but you should be able to adapt what I have done to accomodate this.

Correct me if I'm wrong. Basically qty1 for any order should be from first array and qty2 from the second array. By that logic, the solution is:

 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))

You can use this simple solution, it uses Object.assign to create a copy from one object to another object. Here temp obj is used for a place holder, thus not affecting the original objects.

//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 Fiddle https://jsfiddle.net/ejqn8c6b/1/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM