I have two sets of arrays data, one for orders and one for picking orders. The order id of those arrays is the same. Data for picking orders is nested arrays. There is one value named orderHasAlcohol
in the Picking
orders data. I'd like to make a new array in which I can add orderHasAlcohol
from the Orders
data.
I am not sure how I can do it.
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});
P.S.: I am using ramda for my function validation. it would be nice to create new array by using ramda. but not necessary.
CodePudding user response:
I would suggest something like this:
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;
});
If you read this code, you'll see that the first part retrieves the information needed from pickingOrder
and the second one applies it to your array. If it is in your hands, I would suggest simplifying the structure of the pickingOrder
array in order to optimize the reading process, but anyways, this should work as well.
CodePudding user response:
You could write a generator that yields the objects of interest from the picking order object.
I would also key the main data by id, so you can quickly find an object by id and merge more data into it.
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);
CodePudding user response:
I don't know Ramda but with native js it should looks like this :
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);