我写了一个钩子来根据月份计算销售额来设置图表数据。
工作很好,但我不满意。
是否有不同或简单的方法来避免重复并使代码干净且可扩展!
注意:我不与公司或团队合作 - (自学)
我想计算当月每天的总数并返回新的对象数组
功能:
const month = (date) => new Date(date).toLocaleString('default', { month: 'long' });
export const useGetChartData = (orders) => {
const orderTotal = orders.length
const orderTotalsArray = orders.map(order => (+order.total) + (+order.total_tax));
const sumOrders = orderTotalsArray?.reduce((inc, a) => inc + a, 0);
const getMonthFromDateAndTotals = orders?.map(order => (
{
date: (order.date_paid ? month(order.date_paid) : month(order.date_modified)),
total: +order.total + +order.total_tax
}));
const sendToChart = getMonthFromDateAndTotals.filter(o => o.total > 0);
//filter!
const January = sendToChart.filter((d) => d.date == 'January')
const February = sendToChart.filter((d) => d.date == 'February')
const March = sendToChart.filter((d) => d.date == 'March')
const April = sendToChart.filter((d) => d.date == 'April')
const May = sendToChart.filter((d) => d.date == 'May')
const June = sendToChart.filter((d) => d.date == 'June')
const July = sendToChart.filter((d) => d.date == 'July')
const August = sendToChart.filter((d) => d.date == 'August')
const September = sendToChart.filter((d) => d.date == 'September')
const October = sendToChart.filter((d) => d.date == 'October')
const November = sendToChart.filter((d) => d.date == 'November')
const December = sendToChart.filter((d) => d.date == 'December')
//
const totalsPerMonths = [
//reduce!
{ month: 'January', total: January?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'February', total: February?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'March', total: March?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'April', total: April?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'May', total: May?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'June', total: June?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'July', total: July?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'August', total: August?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'September', total: September?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'October', total: October?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'November', total: November?.reduce((inc, a) => inc + a.total, 0) },
{ month: 'December', total: December?.reduce((inc, a) => inc + a.total, 0) },
//
];
const dataVisualizationToChart = totalsPerMonths.filter(vd => vd.total > 0);
return {
dataVisualizationToChart,
orderTotal,
sumOrders
};
};
用途:
const { data: orders, isLoading: ordersLoading, errors: orderErrors} = useGetShopData("orders");
const { dataVisualizationToChart, sumOrders } = useGetChartData(orders)
返回:
{
"dataVisualizationToChart": [
{"month": "February","total": 1875.96},
{ "month": "March", "total": 1362.46},
{ "month": "April","total": 66.05000000000004},
],
"orderTotal": 70,
"sumOrders": 13064
}```
我会建议这样的事情:
创建monthNames对象:将月份的数值映射到字符串名称。
const monthNames = {
'01': 'January',
'02': 'February',
'03': 'March',
'04': 'April',
'05': 'May',
'06': 'June',
'07': 'July',
'08': 'August',
'09': 'September',
'10': 'October',
'11': 'November',
'12': 'December'
};
我没有为每个月创建单独的数组,然后计算总数,而是使用reduce 在一次传递中按月对总数进行分组。
totalsPerMonths 的结果将是一个对象,其中键是唯一日期(月份),值是每个月的总和。
const totalsPerMonths = sendToChart.reduce((acc, current) => {
if (!acc[current.date]) {
acc[current.date] = 0;
}
acc[current.date] += current.total;
return acc;
}, {});
在这里,我使用 MonthNames 映射将月份的数值提取到字符串名称中。
减少后,我通过迭代分组和减少对象的键来构造 dataVisualizationToChart。
const dataVisualizationToChart = Object.keys(totalsPerMonths).map(dateStr => {
const [year, month] = dateStr.split('-');
return {
month: monthNames[month],
total: totalsPerMonths[dateStr]
};
});
希望我的解决方案对您有帮助!
我建议你在 LeetCode 上解决与数组和结果聚合相关的问题。它确实有助于解决未来类似的任务!