JavaScript两个数组合并成新的数组



我有两组数组数据,一组用于订单,另一组用于挑选订单。这些数组的顺序id是相同的。挑选订单的数据是嵌套数组。在Picking订单数据中有一个名为orderHasAlcohol的值。我想做一个新的数组,我可以从Orders数据中添加orderHasAlcohol

我不知道该怎么做。

const ordersData = [
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-14",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "1234", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "123", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "198", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "125", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
];

const pickingOrder = {
ordersPickedAndDone: {
orderCount: 0,
rows: [],
},
ordersPickedAndPaid: {
orderCount: 0,
rows: [],
},
ordersPickedCanStart: {
orderCount: 2,
rows: [
{
orderHasAlcohol: false,
orderId: "123",
},
{
orderHasAlcohol: true,
orderId: "198",
},
],
},
ordersPickingProgress: {
orderCount: 2,
rows: [
{
pickingRun: 1,
partitions: [
{
orderHasAlcohol: false,
orderId: "125",
},
{
orderHasAlcohol: true,
orderId: "1234",
},
],
},
],
},
};

// This is my expected arrays output
const expectedArrays = [
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-14",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "1234", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
orderHasAlcohol: true,
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "123", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
orderHasAlcohol: false,
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "198", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
orderHasAlcohol: true,
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "125", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
orderHasAlcohol: false,
},
];
console.log({expectedArrays});

注::我使用ramda为我的功能验证。这将是很好的创建新的数组使用ramda。但没必要。

我不知道Ramda,但是使用native js应该是这样的:

首先将expectedArrays简化为objectarray,将orderId关联到属性orderHasAlcohol:

let pickingOrderSimplified = Object.fromEntries(Object.keys(pickingOrder).map(key => {
return  pickingOrder[key].rows.length > 0 && pickingOrder[key].rows.at(0).partitions ?  
pickingOrder[key].rows.map(row => row.partitions).flat() : 
pickingOrder[key].rows;
}).flat().map(el => [el.orderId, el.orderHasAlcohol]));

可以合并数组:

let res = ordersData.map(data => ({
...data,
orderHasAlcohol: pickingOrderSimplified[data.id]
}));
console.log(res);

我建议这样做:

let alcoholContentMap = {};
for (const key of Object.keys(pickingOrder)) {
const orderCount = pickingOrder[key].orderCount;
if (orderCount > 0) {
for (const index = 0; index < orderCount; index++) {
const currentOrder = pickingOrder[key].rows[index];
if ('partitions' in currentOrder) {
for (const partition of currentOrder)
alcoholContentMap[partition.orderId] = partition.orderHasAlcohol;
} else {
alcoholContentMap[currentOrder.orderId] = partition.orderHasAlcohol;
}
}
}
}
const expectedArrays = ordersData.map(order => {
if (order.orderId in alcoholContentMap) {
return {
...order,
orderHasAlcohol: alcoholContentMap[order.orderId]
}
} else return order;
});

如果您阅读这段代码,您将看到第一部分从pickingOrder检索所需的信息,第二部分将其应用于您的数组。如果是在你的手中,我建议简化pickingOrder数组的结构来优化阅读过程,但无论如何,这应该工作。

您可以编写一个生成器,从拾取顺序对象中产生感兴趣的对象。

我也将主数据按id键,所以你可以快速找到一个对象的id和合并更多的数据到它。

const ordersData = [{additionalInfo: null,comment: null,deliveryDate: "2022-07-14",deliveryMethod: "PICKUP",deliveryTime: "10-12",discountCode: null,id: "1234",orderStatus: "NEW",paymentMethod: "ON_DELIVERY",paymentStatus: "UNAVAILABLE",storeId: "12345",},{additionalInfo: null,comment: null,deliveryDate: "2022-07-23",deliveryMethod: "PICKUP",deliveryTime: "10-12",discountCode: null,id: "123",orderStatus: "NEW",paymentMethod: "ON_DELIVERY",paymentStatus: "UNAVAILABLE",storeId: "12345",},{additionalInfo: null,comment: null,deliveryDate: "2022-07-23",deliveryMethod: "PICKUP",deliveryTime: "10-12",discountCode: null,id: "198",orderStatus: "NEW",paymentMethod: "ON_DELIVERY",paymentStatus: "UNAVAILABLE",storeId: "12345",},{additionalInfo: null,comment: null,deliveryDate: "2022-07-23",deliveryMethod: "PICKUP",deliveryTime: "10-12",discountCode: null,id: "125",orderStatus: "NEW",paymentMethod: "ON_DELIVERY",paymentStatus: "UNAVAILABLE",storeId: "12345",},];
const pickingOrder = {ordersPickedAndDone: {orderCount: 0,rows: [],},ordersPickedAndPaid: {orderCount: 0,rows: [],},ordersPickedCanStart: {orderCount: 2,rows: [{orderHasAlcohol: false,orderId: "123",},{orderHasAlcohol: true,orderId: "198",},],},ordersPickingProgress: {orderCount: 2,rows: [{pickingRun: 1,partitions: [{orderHasAlcohol: false,orderId: "125",},{orderHasAlcohol: true,orderId: "1234",},],},],},};
// Yield objects from given data structure that have "orderId" property
function* iterOrderInfo(obj) {
if (Object(obj) !== obj) return;
if (obj.orderId) yield obj;
for (const value of Object.values(obj)) {
yield* iterOrderInfo(value);
}
}
// Key the main data by order id
const map = new Map(ordersData.map(obj => [obj.id, {...obj}]));
// Associate objects retrieved from picking order by id and merge them into the data
for (const {orderId, ...rest} of iterOrderInfo(pickingOrder)) {
Object.assign(map.get(orderId), rest);
}
// Retrieve the results 
const result = [...map.values()];
console.log(result);

实用的解决方案

const re = /"orderHasAlcohol":(true|false),"orderId":("d+")/g;
let alco = [...JSON.stringify(pickingOrder).matchAll(re)]
.reduce((acc, entry) => {
const key = entry[2].replaceAll('"', ""); /// this could be more elegant
acc[key] = entry[1] === "true";
return acc;
}, {});
console.log(alco)
ordersData.forEach(order => order.hasAlcohol = alco[order.id] ? ? false)
console.log(ordersData)
<script>
const ordersData = [{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-14",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "1234", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "123", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "198", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
{
additionalInfo: null,
comment: null,
deliveryDate: "2022-07-23",
deliveryMethod: "PICKUP",
deliveryTime: "10-12",
discountCode: null,
id: "125", // orderId
orderStatus: "NEW",
paymentMethod: "ON_DELIVERY",
paymentStatus: "UNAVAILABLE",
storeId: "12345",
},
];
const pickingOrder = {
ordersPickedAndDone: {
orderCount: 0,
rows: [],
},
ordersPickedAndPaid: {
orderCount: 0,
rows: [],
},
ordersPickedCanStart: {
orderCount: 2,
rows: [{
orderHasAlcohol: false,
orderId: "123",
},
{
orderHasAlcohol: true,
orderId: "198",
},
],
},
ordersPickingProgress: {
orderCount: 2,
rows: [{
pickingRun: 1,
partitions: [{
orderHasAlcohol: false,
orderId: "125",
},
{
orderHasAlcohol: true,
orderId: "1234",
},
],
}, ],
},
};
</script>

最新更新