JavaScript中如何将数组对象的日期month值转为月份名称并排序
实现方案
拿到Django接口返回的原始数据后,通过排序+格式转换两步处理即可得到符合chartist要求的格式,全程用JavaScript原生API实现,不需要引入额外依赖。
核心数据处理函数
// 英文月份名称映射,索引和Date对象getMonth()返回值(0-11)一一对应 const EN_MONTHS = [ "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" ]; /** * 处理接口返回的月度统计数据 * @param {Array} rawData 接口返回的原始数组 * @returns {Array} 排序后、月份转为英文名称的目标数组 */ function formatMonthlyData(rawData) { // 1. 先按时间升序排序,避免接口返回顺序混乱 const sortedList = [...rawData].sort((prev, next) => { return new Date(prev.month).getTime() - new Date(next.month).getTime(); }); // 2. 转换ISO日期为英文月份名 return sortedList.map(item => { const currentDate = new Date(item.month); return { month: EN_MONTHS[currentDate.getMonth()], total: item.total }; }); }
注意点
- 排序前对原始数组做浅拷贝,不会修改接口返回的原数据,避免副作用
- 直接用
Date解析带时区的ISO格式字符串,自动对齐时区计算对应月份,不会出现跨时区导致的月份计算错误
React + Chartist 接入示例
在组件的接口请求回调中调用上述处理函数,将处理后的数据组装成chartist要求的格式即可:
import { useEffect, useState } from 'react'; import ChartistGraph from 'react-chartist'; export default function MonthlyEventChart() { const [chartConfig, setChartConfig] = useState({ labels: [], series: [[]] }); useEffect(() => { // 替换为实际的Django接口地址 fetch('/api/monthly-event-count/') .then(res => res.json()) .then(raw => { const formattedData = formatMonthlyData(raw); setChartConfig({ labels: formattedData.map(item => item.month), series: [formattedData.map(item => item.total)] }); }); }, []); return ( <div className="chart-container"> <ChartistGraph data={chartConfig} type="Bar" // 根据需求替换为Line/Bar等你需要的图表类型 options={{ axisY: { onlyInteger: true } }} /> </div> ); }
可选扩展:补全缺失月份
如果你的业务要求连续展示时间区间内所有月份(比如示例中6月到8月之间缺失7月时,自动补total:0的7月数据),可以在排序后增加补全逻辑:
function fillEmptyMonths(sortedData) { if (sortedData.length === 0) return []; const startDate = new Date(sortedData[0].month); const endDate = new Date(sortedData[sortedData.length - 1].month); const fullList = []; let cursor = new Date(startDate.getFullYear(), startDate.getMonth(), 1); while (cursor <= endDate) { const matchItem = sortedData.find(item => { const itemDate = new Date(item.month); return itemDate.getFullYear() === cursor.getFullYear() && itemDate.getMonth() === cursor.getMonth(); }); fullList.push(matchItem || { month: cursor.toISOString(), total: 0 }); cursor.setMonth(cursor.getMonth() + 1); } return fullList; }
调用时在排序后、转月份名前传入该函数即可:
function formatMonthlyData(rawData) { const sortedList = [...rawData].sort((prev, next) => { return new Date(prev.month).getTime() - new Date(next.month).getTime(); }); const fullMonthList = fillEmptyMonths(sortedList); // 补全缺失月份 return fullMonthList.map(item => { const currentDate = new Date(item.month); return { month: EN_MONTHS[currentDate.getMonth()], total: item.total }; }); }
内容的提问来源于stack exchange,提问作者Publius
相关产品推荐
相关产品推荐

