You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中按类别统计年份频次并生成堆叠折线图数据的方案求助

问题:统计类别年份频次并生成总计数据用于堆叠折线图

我正尝试在JavaScript中构建输入与目标输出数据的映射,统计每个类别下各年份的出现次数,同时生成总计数据以填充堆叠折线图(每条线对应一个类别,额外一条为总计)。

输入数据

const inputDates = [
    {
        title: 'categoryOne',
        years: ['2021', '2021', '2023', '2022', '2022', '2021']
    },
    {
        title: 'categoryTwo',
        years: ['2021', '2022', '2022', '2022', '2022', '2023']
    },
    {
        title: 'categoryThree',
        years: ['2022', '2023', '2023']
    },
];

期望输出

const chartData = [
    {
        title: 'categoryOne',
        years: [
            {year: '2021', count: 3},
            {year: '2022', count: 2},
            {year: '2023', count: 1},
        ]
    },
    {
        title: 'categoryTwo',
        years: [
            {year: '2021', count: 1},
            {year: '2022', count: 4},
            {year: '2023', count: 1},
        ]
    },
    {
        title: 'categoryThree',
        years: [
            {year: '2022', count: 1},
            {year: '2023', count: 2},
        ]
    },
    {
        title: 'total',
        years: [
            {year: '2021', count: 4},
            {year: '2022', count: 7},
            {year: '2023', count: 4},
        ]
    },
];

实现思路与代码

1. 编写年份统计工具函数

先实现一个通用函数,接收年份数组,返回按{year, count}格式整理的统计结果:

function countYears(yearArray) {
    // 用reduce统计每个年份的出现次数
    const countMap = yearArray.reduce((acc, year) => {
        acc[year] = (acc[year] || 0) + 1;
        return acc;
    }, {});
    // 将统计对象转成目标数组格式
    return Object.entries(countMap).map(([year, count]) => ({ year, count }));
}

2. 处理所有类别数据

遍历输入数组,对每个类别调用工具函数,生成处理后的类别列表:

const processedCategories = inputDates.map(item => ({
    title: item.title,
    years: countYears(item.years)
}));

3. 计算总计数据

收集所有类别的年份统计结果,累加每个年份的总次数:

// 合并所有类别的统计数据,生成总计数映射
const totalCountMap = processedCategories.reduce((acc, category) => {
    category.years.forEach(({ year, count }) => {
        acc[year] = (acc[year] || 0) + count;
    });
    return acc;
}, {});
// 转成目标格式的总计数据
const totalData = {
    title: 'total',
    years: Object.entries(totalCountMap).map(([year, count]) => ({ year, count }))
};

4. 合并最终结果

把处理后的类别数据和总计数据合并,得到最终的chartData:

const chartData = [...processedCategories, totalData];

完整代码

const inputDates = [
    { title: 'categoryOne', years: ['2021', '2021', '2023', '2022', '2022', '2021'] },
    { title: 'categoryTwo', years: ['2021', '2022', '2022', '2022', '2022', '2023'] },
    { title: 'categoryThree', years: ['2022', '2023', '2023'] },
];

function countYears(yearArray) {
    const countMap = yearArray.reduce((acc, year) => {
        acc[year] = (acc[year] || 0) + 1;
        return acc;
    }, {});
    return Object.entries(countMap).map(([year, count]) => ({ year, count }));
}

const processedCategories = inputDates.map(item => ({
    title: item.title,
    years: countYears(item.years)
}));

const totalCountMap = processedCategories.reduce((acc, category) => {
    category.years.forEach(({ year, count }) => {
        acc[year] = (acc[year] || 0) + count;
    });
    return acc;
}, {});

const totalData = {
    title: 'total',
    years: Object.entries(totalCountMap).map(([year, count]) => ({ year, count }))
};

const chartData = [...processedCategories, totalData];
console.log(chartData);

内容的提问来源于stack exchange,提问作者Phil S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:13:18