我有两个API响应
第一个API响应(ProjectAPI.post('/ ALLAPI / API1',null,null,requestBody的响应))-参见问题的后面部分
[
{
"Location": "Boston",
"OrderNo": "406643",
"Qty": "46.1650",
"OrderDate": null,
"Status": null
}
]
第二个API响应(ProjectAPI.post('/ ALLAPI / API2',null,null,requestBody的响应))-参见问题的后面部分
[
{
"Location": "Boston",
"OrderNo": "406643",
"Qty": "22.27",
"OrderDate": "28/11/0018",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty": "21.94",
"OrderDate": "01/03/0019",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty": "65.36",
"OrderDate": "01/03/0019",
"Status": null
}
]
现在两个API都有一个“数量”字段,我必须在需要同时包含两个数量的地方创建一个新变量。如果对于特定的OrderNo和Location组合,说Qty1-存在第一个API响应字段Qty但不存在第二个API Qty字段,那么我们应该将Qty2插入为0,同样如果Qty2-存在第二个APIs响应字段Qty但第一个API数量字段不存在,那么我们应该将数量1插入0。
我们还要考虑两个API中的任何一个都可以完全返回空白数组
请注意,比较参数为OrderNo和Location。
我想基本上合并两个API响应并创建一个CombinedResponse
我的组合响应必须在对象数组中包含三个对象
[
{
"Location": "Boston",
"OrderNo": "406643",
"Qty1": "46.1650",
"Qty2": "22.27",
"OrderDate": "28/11/0018",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty1": "0",
"Qty2": "21.94",
"OrderDate": "01/03/0019",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty1": "0",
"Qty2": "65.36",
"OrderDate": "01/03/0019",
"Status": null
}
]
我已经使用Lodash了,但是得到了一些异常结果
我的代码
ProjectAPI.post('/ALLAPI/API1', null, null, requestBody)
.then((response) => {//1st API response (as mentioned above)
const combinedResponse = [];
for (let i = 0; i < response.length; i = i + 1) {
const obj = response[i];
obj.Qty1 = response[i].Qty;
obj.Qty2 = 0;
combinedResponse.push(obj);
}
ProjectAPI.post('/ALLAPI/API2', null, null, requestBody)
.then((innerResponse) => {//2nd API response (as mentioned above)
for (let i = 0; i < innerResponse.length; i = i + 1) {
const outerIndex = _.findIndex(combinedResponse, (o) => { return o.Location === innerResponse[i].Location && o.OrderNo === innerResponse[i].OrderNo; });
let obj = {};
if(outerIndex === -1) {
obj = innerResponse[i];
obj.Qty1 = 0;
obj.Qty2 = innerResponse[i].Qty;
combinedResponse.push(obj);
} else {
combinedResponse[outerIndex].Qty2 = innerResponse[i].Qty;
}
}
this.setState({ combinedResponse: combinedResponse });
}).catch((err) => {
console.log('There was an error with ', err);
});
}).catch((err) => {
console.log('There was an error with ', err);
});
我的代码没有显示最后一个/第三个对象(仅获取第一个两个对象)
[
{
"Location": "Boston",
"OrderNo": "406643",
"Qty1": "46.1650",
"Qty2": "22.27",
"OrderDate": "28/11/0018",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty1": "0",
"Qty2": "21.94",
"OrderDate": "01/03/0019",
"Status": null
}
]
如果有人可以纠正我的代码以使我得到正确的CombinedResponse,这将非常有帮助。我对Lodash / JQuery解决方案不感兴趣。我想要一个普通香草JS解决方案。请提供通用解决方案。有人可以在这方面帮助我。在我的代码中,最后一个对象未显示在对象的最终数组中。我的方法也很复杂。如果有人可以提供更简单的响应以及小提琴/ JSFiddle,那么这对我会有很大帮助。
如果有人回答我的查询,请忽略API调用,只需使用两个API响应即可。
在Plain ES5或ES6中需要一个解决方案,而在JQuery / Underscore / Lodash中则不需要。
答案 0 :(得分:0)
当JS本机函数简洁时,我不希望使用诸如lodash之类的依赖项。
1)我建议在将map
字段重命名为Qty
时,使用Qty1
(mdn)从您的第一个响应中初始化您的组合响应。
2)然后使用forEach
(mdn)和
3)使用find
(mdn)从您的第一个响应中找到相应的顺序。
4)如果您在响应1中找到了相应的订单,请更新其Qty2
字段。否则,请在您的combinedResponses
中插入新订单。
let response1 = [
{
"Location": "Boston",
"OrderNo": "406643",
"Qty": "46.1650",
"OrderDate": null,
"Status": null
}
];
let response2 = [
{
"Location": "Boston",
"OrderNo": "406643",
"Qty": "22.27",
"OrderDate": "28/11/0018",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty": "21.94",
"OrderDate": "01/03/0019",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty": "65.36",
"OrderDate": "01/03/0019",
"Status": null
}
];
let combinedResponses = response1.map(({Location, OrderNo, Qty, OrderDate, Status}) =>
({Location, OrderNo, Qty1: Qty, Qty2: 0, OrderDate, Status,}));
response2.forEach(({Location, OrderNo, Qty, OrderDate, Status}) => {
let find = combinedResponses.find(({Location: locationC, OrderNo: orderNoC})=> locationC === Location && orderNoC === OrderNo);
if (find)
find.Qty2 = Qty;
else
combinedResponses.push({Location, OrderNo, Qty1: 0, Qty2: Qty, OrderDate, Status,});
});
console.log(combinedResponses);
PS,同样值得一提的是,您应该研究展平承诺/然后嵌套以使其更具可读性。
答案 1 :(得分:0)
鉴于orderNo
唯一地标识一个实体,该实体将是一种简单,通用且易于理解的解决方案:
let array1 = [{
"Location": "Boston",
"OrderNo": "406643",
"Qty": "46.1650",
"OrderDate": null,
"Status": null
}]
let array2 = [{
"Location": "Boston",
"OrderNo": "406643",
"Qty": "22.27",
"OrderDate": "28/11/0018",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty": "21.94",
"OrderDate": "01/03/0019",
"Status": null
},
{
"Location": "Boston",
"OrderNo": "526209",
"Qty": "65.36",
"OrderDate": "01/03/0019",
"Status": null
}
]
let mergedArray = [];
let orderNumbers = array2.map(x => x.OrderNo);
array1.forEach((order, i) => {
let mergedOrder = {
"Location": order.Location,
"OrderNo": order.OrderNo,
"Qty1": order.Qty,
"OrderDate": order.OrderDate,
"Status": order.Status
}
let index = orderNumbers.indexOf(order.OrderNo);
if (index <= 0) {
mergedOrder.Qty2 = array2[index].Qty;
//remove used element
array2.splice(index, 1);
orderNumbers.splice(index, 1);
} else {
mergedOrder.Qty2 = "0";
}
mergedArray.push(mergedOrder);
})
//insert the remaining elements with 0 as qty1
array2.forEach(order => {
let mergedOrder = {
"Location": order.Location,
"OrderNo": order.OrderNo,
"Qty2": order.Qty,
"OrderDate": order.OrderDate,
"Status": order.Status
}
mergedOrder.Qty1 = "0";
mergedArray.push(mergedOrder);
});
console.log(mergedArray);
其中array1
和array2
是您的2条回复。
还请注意,例如,使用indexOf
代替find
有利于浏览器兼容性(尤其是IE)。
编辑:添加了jsfiddle。请原谅我不要在任何地方都使用camelCase,但希望您能理解。
答案 2 :(得分:0)
问题是您的两个匹配mongoclientoptions vs mongoclientsettings
和Location
的项目都在同一个orderNo
数组中,因此当您遍历该数组并找到带有{{ 1}}和innerResponse
,分别设置Location: 'Boston'
和orderNo: 526209
,然后再次循环时,找到匹配的元素,并在obj.Qty = 0
块中用{匹配obj.Qty2 = innerResponse[i].Qty;
中的值,因此您要么需要设置else
解决方案是,如果没有匹配的Qty2
而不是设置obj
和Qt1 = innerResponse[i].Qty
,而如果没有匹配的obj.Qty1 = 0;
则设置obj.Qty2 = innerResponse[i].Qty;
然后打开在下一个循环中,它将添加一个obj
,您将获得两个值。
更好的解决方案是在创建的对象上创建obj.Qty1 = innerResponse[i].Qty;
数组,然后可以根据需要添加任意数量的Qty值。
对于索引,您不再需要使用破折号,ES6中现在有了一个本机的findIndex,因此您可以通过以下方式获取索引:
obj
由于您使用的是ES6,因此可以使用Array.forEach替换for循环以获得更清晰的代码。
在原始函数中使用Qty2
和Qty
的解决方案如下:
const outerIndex = combinedResponse.findIndex(o => o.Location === innerResponse[i].Location && o.OrderNo === innerResponse[i].OrderNo);
这是使用数组而不是命名键的解决方案:
Qty1
希望有帮助:-)
答案 3 :(得分:0)
此解决方案不会更改原始API响应。
let response1 = [{
Location: 'Boston',
OrderNo: '406643',
Qty: '46.1650',
OrderDate: null,
Status: null,
}, ];
let response2 = [{
Location: 'Boston',
OrderNo: '406643',
Qty: '22.27',
OrderDate: '28/11/0018',
Status: null,
},
{
Location: 'Boston',
OrderNo: '526209',
Qty: '21.94',
OrderDate: '01/03/0019',
Status: null,
},
{
Location: 'Boston',
OrderNo: '526209',
Qty: '65.36',
OrderDate: '01/03/0019',
Status: null,
},
];
const combinedResponse = response2.map(o => {
const found = response1.find(v => v.Location === o.Location && v.OrderNo === o.OrderNo) || {};
const clone = Object.assign({}, o);
clone.Qty2 = clone.Qty || '0';
clone.Qty1 = found.Qty || '0';
delete clone.Qty;
return clone;
});
console.log(combinedResponse);