How to call reduce over empty array and assign new properties
I have an object with default properties and two arrays, where one of these is empty. The empty array has the possibility to not be empty on some occasions, but I still want to loop over it. If the array is empty, reduce won't be called and I will be missing some properties, so the idea is to have some default properties in the object in case the array is empty. The expected result is something like this:
[{
"playedOffTickets": 60,
"playedOffRevenue": 1730.5,
"Transactions.deliveryMethod": "Print At Home Delivery",
"soldTickets": 0,
"soldRevenue": 0,
},
{
"playedOffTickets": 43,
"playedOffRevenue": 1160,
"Transactions.deliveryMethod": "Postal Delivery",
"soldTickets": 0,
"soldRevenue": 0,
},
{
"playedOffTickets": 12,
"playedOffRevenue": 348,
"Transactions.deliveryMethod": "Cobo Delivery",
"soldTickets": 0,
"soldRevenue": 0,
},
{
"playedOffTickets": -3,
"playedOffRevenue": -87,
"Transactions.deliveryMethod": "",
"soldTickets": 0,
"soldRevenue": 0,
}];
But the response I'm getting is not what I want. What am I doing wrong? Thanks in advance!
const productMap = {
soldTickets: 0,
soldRevenue: 0,
playedOffTickets: 0,
playedOffRevenue: 0,
};
const arr1 = [];
const arr2 = [
{
"Transactions.deliveryMethod": "Print At Home Delivery",
"Transactions.itemCount": "60",
"Transactions.revenue": "1730.5"
},
{
"Transactions.deliveryMethod": "Postal Delivery",
"Transactions.itemCount": "43",
"Transactions.revenue": "1160"
},
{
"Transactions.deliveryMethod": "Cobo Delivery",
"Transactions.itemCount": "12",
"Transactions.revenue": "348"
},
{
"Transactions.deliveryMethod": "",
"Transactions.itemCount": "-3",
"Transactions.revenue": "-87"
}
];
arr1.reduce((p, salesData) => {
const product = salesData["Transactions.deliveryMethod"];
p[product] = p[product] || {};
const soldTickets = Number(salesData["Transactions.itemCount"]);
const soldRevenue = Number(salesData["Transactions.revenue"]);
p[product].soldTickets = p[product].soldTickets || 0;
p[product].soldTickets += soldTickets;
p[product].soldRevenue = p[product].soldRevenue || 0;
p[product].soldRevenue += soldRevenue;
p[product]["Transactions.deliveryMethod"] = product;
return p;
}, productMap);
arr2.reduce((p, playedOffData) => {
const product = playedOffData["Transactions.deliveryMethod"];
p[product] = p[product] || {};
const playedOffTickets = Number(playedOffData["Transactions.itemCount"]);
const playedOffRevenue = Number(playedOffData["Transactions.revenue"]);
p[product].playedOffTickets = p[product].playedOffTickets || 0;
p[product].playedOffTickets += playedOffTickets;
p[product].playedOffRevenue = p[product].playedOffRevenue || 0;
p[product].playedOffRevenue += playedOffRevenue;
p[product]["Transactions.deliveryMethod"] = product;
return p;
}, productMap);
const productMapData = Object.values(productMap);
console.log(productMapData)
Solution 1:
I would suggest adding a productMapDefaults
object, we'd use this whenever we want to create a new entry in the productMap object.
One can then customize as necessary to add new properties.
const productMap = {};
const productMapDefaults = {
soldTickets: 0,
soldRevenue: 0,
playedOffTickets: 0,
playedOffRevenue: 0
}
const arr1 = [];
const arr2 = [
{
"Transactions.deliveryMethod": "Print At Home Delivery",
"Transactions.itemCount": "60",
"Transactions.revenue": "1730.5"
},
{
"Transactions.deliveryMethod": "Postal Delivery",
"Transactions.itemCount": "43",
"Transactions.revenue": "1160"
},
{
"Transactions.deliveryMethod": "Cobo Delivery",
"Transactions.itemCount": "12",
"Transactions.revenue": "348"
},
{
"Transactions.deliveryMethod": "",
"Transactions.itemCount": "-3",
"Transactions.revenue": "-87"
}
];
arr1.reduce((p, salesData) => {
const product = salesData["Transactions.deliveryMethod"];
// Use productMapDefaults as template when creating new entry...
p[product] = p[product] || { ...productMapDefaults };
const soldTickets = Number(salesData["Transactions.itemCount"]);
const soldRevenue = Number(salesData["Transactions.revenue"]);
p[product].soldTickets = p[product].soldTickets || 0;
p[product].soldTickets += soldTickets;
p[product].soldRevenue = p[product].soldRevenue || 0;
p[product].soldRevenue += soldRevenue;
p[product]["Transactions.deliveryMethod"] = product;
return p;
}, productMap);
arr2.reduce((p, playedOffData) => {
const product = playedOffData["Transactions.deliveryMethod"];
// Use productMapDefaults as template when creating new entry...
p[product] = p[product] || { ...productMapDefaults };
const playedOffTickets = Number(playedOffData["Transactions.itemCount"]);
const playedOffRevenue = Number(playedOffData["Transactions.revenue"]);
p[product].playedOffTickets = p[product].playedOffTickets || 0;
p[product].playedOffTickets += playedOffTickets;
p[product].playedOffRevenue = p[product].playedOffRevenue || 0;
p[product].playedOffRevenue += playedOffRevenue;
p[product]["Transactions.deliveryMethod"] = product;
return p;
}, productMap);
const productMapData = Object.values(productMap);
console.log(productMapData)
.as-console-wrapper { max-height: 100% !important; top: 0; }