Reputation: 85
I am looking to solve 2 problems here
items
array based on based on orderNo
tracking.json
into the orders array.So far I have only managed to get started with the grouping.
//orders.json
const orders = [
{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "[email protected]",
"articleNo": "A",
"articleImageUrl": "watch.jpg",
"quantity": 1,
"product_name": "Watch"
},
{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "[email protected]",
"articleNo": "B",
"articleImageUrl": "belt.jpg",
"quantity": 2,
"product_name": "Belt"
},
{
"orderNo": "2",
"tracking_number": "002",
"courier": "FedEx",
"street": "637 Britannia Drive",
"zip_code": 94591,
"city": "Vallejo",
"destination_country": "USA",
"email": "[email protected]",
"articleNo": "",
"articleImageUrl": "",
"quantity": "",
"product_name": ""
}
];
//tracking.json
const tracking = [{
"tracking_number": "001",
"location": "",
"timestamp": "2018-04-01T00:00:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
},
{
"tracking_number": "002",
"location": "",
"timestamp": "2018-04-06T05:58:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
}
]
//expected output data.json
const data = [
{
"orderNo":"1",
"tracking_number":"001",
"courier":"FedEx",
"street":"1745 T Street Southeast",
"zip_code":"20020",
"city":"Louisville",
"destination_country":"USA",
"email":"[email protected]",
"articleNo":"A",
"articleImageUrl":"watch.jpg",
"quantity":"1",
"product_name":"Watch",
"items":[
{
"articleNo":"A",
"articleImageUrl":"watch.jpg",
"quantity":"1",
"product_name":"Watch"
},
{
"articleNo":"B",
"articleImageUrl":"belt.jpg",
"quantity":"2",
"product_name":"Belt"
}
],
"tracking":{
"tracking_number":"001",
"location":null,
"timestamp":"2018-04-01T00:00:00.000Z",
"status":"Scheduled",
"status_text":"Order processed",
"status_details":"The order has been processed."
}
},
{
"orderNo": "2",
"tracking_number": "002",
"courier": "FedEx",
"street": "637 Britannia Drive",
"zip_code": 94591,
"city": "Vallejo",
"destination_country": "USA",
"email": "[email protected]",
"articleNo": "",
"articleImageUrl": "",
"quantity": "",
"product_name": "",
"items":[
],
"tracking":{
"tracking_number": "002",
"location": "",
"timestamp": "2018-04-06T05:58:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
}
}
]
const groupBy = key => array =>
array.reduce(
(objectsByKeyValue, obj) => ({
...objectsByKeyValue,
[obj[key]]: (objectsByKeyValue[obj[key]] || []).concat(obj)
}),
{}
);
const groupByOrders = groupBy('orderNo');
I am looking to get the data in the format shown in data.json
This is the current code along with the data
Upvotes: 0
Views: 96
Reputation: 386730
You could take two objects as reference to same orderNo
and tracking_number
.
For adding an oder to the result set remove item properties and take a new object of this properties.
const
orders = [{ orderNo: "1", tracking_number: "001", courier: "FedEx", street: "1745 T Street Southeast", zip_code: 20020, city: "Louisville", destination_country: "USA", email: "[email protected]", articleNo: "A", articleImageUrl: "watch.jpg", quantity: 1, product_name: "Watch" }, { orderNo: "1", tracking_number: "001", courier: "FedEx", street: "1745 T Street Southeast", zip_code: 20020, city: "Louisville", destination_country: "USA", email: "[email protected]", articleNo: "B", articleImageUrl: "belt.jpg", quantity: 2, product_name: "Belt" }, { orderNo: "2", tracking_number: "002", courier: "FedEx", street: "637 Britannia Drive", zip_code: 94591, city: "Vallejo", destination_country: "USA", email: "[email protected]", articleNo: "", articleImageUrl: "", quantity: "", product_name: "" }],
tracking = [{ tracking_number: "001", location: "", timestamp: "2018-04-01T00:00:00.000Z", status: "OrderProcessed", status_text: "Order processed", status_details: "The order has been processed." }, { tracking_number: "002", location: "", timestamp: "2018-04-06T05:58:00.000Z", status: "OrderProcessed", status_text: "Order processed", status_details: "The order has been processed." }],
keys = ["articleNo", "articleImageUrl", "quantity", "product_name"],
items = {},
trackings = {},
result = [];
for (let order of orders) {
const item = {};
for (const key of keys) {
let value;
({ [key]: value, ...order } = order);
item[key] = value;
}
if (!items[order.orderNo]) result.push(items[order.orderNo] = { ...order, items: [] });
if (Object.values(item).some(Boolean)) items[order.orderNo].items.push(item);
trackings[order.tracking_number] = items[order.orderNo];
}
for (const transfer of tracking) trackings[transfer.tracking_number].tracking = transfer;
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 3691
Below is one possible way to achieve the target.
Code Snippet
const groupAndInclude = (base, delta) => {
const result = []; // result array
base.forEach( // iterate over the "orders"
({ // de-structure to directly access specific props
orderNo, tracking_number, articleNo,
articleImageUrl, quantity, product_name,
...rest // remaining props not directly-accessed
}) => {
const foundOrder = result.find( // find if "order" already in "result"
ob => ob.orderNo === orderNo
);
if (foundOrder) { // found a match, simply push "article"-info
if (articleNo.length > 0) { // push to "items" only if not "empty"
foundOrder.items.push({ // to the "items" array
articleNo, articleImageUrl, quantity, product_name
})
}
} else { // match not-found. Add new entry to "result"
const resObj = { // construct the result-object "resObj"
...rest, orderNo // using all relevant "order" props
};
if (articleNo.length > 0) { // do not add "empty" item
resObj.items = [{ // add "items" as an array
articleNo, articleImageUrl, quantity, product_name
}];
} else {
resObj.items = [];
};
const foundTracker = delta.find( // look for "tracking_number"
ob => ob.tracking_number === tracking_number
);
// if "tracking_number" found, add to result-object
if (foundTracker) resObj.tracking = {...foundTracker};
result.push(resObj); // push the result-object to the "result" array
}
}
);
return result; // explicitly return the "result" array
};
const orders = [{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "[email protected]",
"articleNo": "A",
"articleImageUrl": "watch.jpg",
"quantity": 1,
"product_name": "Watch"
},
{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "[email protected]",
"articleNo": "B",
"articleImageUrl": "belt.jpg",
"quantity": 2,
"product_name": "Belt"
},
{
"orderNo": "2",
"tracking_number": "002",
"courier": "FedEx",
"street": "637 Britannia Drive",
"zip_code": 94591,
"city": "Vallejo",
"destination_country": "USA",
"email": "[email protected]",
"articleNo": "",
"articleImageUrl": "",
"quantity": "",
"product_name": ""
}
];
//tracking.json
const tracking = [{
"tracking_number": "001",
"location": "",
"timestamp": "2018-04-01T00:00:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
},
{
"tracking_number": "002",
"location": "",
"timestamp": "2018-04-06T05:58:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
}
];
console.log(groupAndInclude(orders, tracking));
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added in the snippet above.
Upvotes: 2