我有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。此外,我们还必须考虑到两个对象数组中的任何一个都可以完全空白数组。
答案 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);
}
}
});
});