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

JavaScript数组对比合并:生成表格所需结构化数据

表格数据映射处理问题

我正在为后端表格准备数据,需要将数据处理成可直接映射为表格行的结构。表格表头基于查询使用的6个月日期范围,已将其与数据对比合并构建初始对象,但还需与后端返回的另一数组对比补全行数据。

原始数据

Headers数组

const headers = [ "2022-7", "2022-8", "2022-9", "2022-10", "2022-11", "2022-12" ]

Data数组

const data = [
{
        "planDetails": {
            "goals": [
                {
                    "title": "Budget",
                    "frequency": 4
                },
                {
                    "title": "clean",
                    "frequency": 6
                }
            ]
        },
        "setVisits": [
            {
                "goals": [
                    {
                        "k": "clean",
                        "v": 2
                    },
                    {
                        "k": "Budget",
                        "v": 2
                    }
                ],
                "date": "2022-9"
            },
            {
                "goals": [
                    {
                        "k": "clean",
                        "v": 2
                    },
                    {
                        "k": "Budget",
                        "v": 2
                    }
                ],
                "date": "2022-10"
            },
            {
                "goals": [
                    {
                        "k": "Budget",
                        "v": 1
                    },
                    {
                        "k": "clean",
                        "v": 2
                    }
                ],
                "date": "2022-8"
            }
        ]
    }
]

已完成的步骤(最后一步存在问题)

const output = data.shift()
console.log(output)

const newHeader = headers.map(i => new Date(i).toISOString())
/* console.log(newHeader) */

const visits = output.setVisits.map(i => { return {date: new Date(i.date).toISOString(), goals: i.goals}})
/* console.log(visits) */

const result = newHeader.map(item => {
    const info = visits.find(detail => detail.date === item);
    if (info) {
        return {
            date: item,
            goals: info.goals
        }
    } else {
        return {
            date: item,
            goals: 0
        }
    }
})
result.sort((a,b) => a.date > b.date)

let finalArr = []

const next = output.planDetails.goals.forEach(i => {
    let newObj = {}
    if ( result.find(a => a.goals.k === i.title)) {
        newObj = {
            goal: i.title,
            frequency: i.frequency,
            elem1: {
                date: a[0].date,
                count: a[0].goals.v
            },
            elem2: {
                date: a[1].date,
                count: a[1].goals.v
            }
        }
    } else if (!result.find(a => a.goals.k === i.title)) {
        newObj = {
            goal: i.title,
            frequency: i.frequency,
            elems: {
                date: a[0].date,
                count: 0
            }
        }
    }
    finalArr.push(newObj)
})

console.log(finalArr)

最后一步实现存在问题,需要找到一种简洁的方法对比对象的两个字段完成映射,无匹配字段时填充0。

期望的最终数组格式

[
{goal: 'Budget', frequency: 4, elem1: {date: "2022-7", count: 0}, elem2: {date: "2022-8", count: 1}, elem3: {date: "2022-9", count: 2}, elem4: {date: "2022-10", count: 2}, elem5: {date: "2022-11", count: 0}, elem6: {date: "2022-12", count: 0}},
{goal: 'clean', frequency: 6, elem1: {date: "2022-7", count: 0}, elem2: {date: "2022-8", count: 2}, elem3: {date: "2022-9", count: 2}, elem4: {date: "2022-10", count: 2}, elem5: {date: "2022-11", count: 0}, elem6: {date: "2022-12", count: 0}}
]

解决方案

实现思路

  1. 避免日期格式转换带来的匹配问题,直接使用原始headers中的日期字符串。
  2. 将setVisits数据转换为日期-目标值的映射对象,方便快速查询任意日期下的目标完成数。
  3. 遍历每个计划目标,为每个表头日期生成对应的elem字段,无数据时填充count: 0。

完整代码

const headers = [ "2022-7", "2022-8", "2022-9", "2022-10", "2022-11", "2022-12" ]

const data = [
{
        "planDetails": {
            "goals": [
                {
                    "title": "Budget",
                    "frequency": 4
                },
                {
                    "title": "clean",
                    "frequency": 6
                }
            ]
        },
        "setVisits": [
            {
                "goals": [
                    {
                        "k": "clean",
                        "v": 2
                    },
                    {
                        "k": "Budget",
                        "v": 2
                    }
                ],
                "date": "2022-9"
            },
            {
                "goals": [
                    {
                        "k": "clean",
                        "v": 2
                    },
                    {
                        "k": "Budget",
                        "v": 2
                    }
                ],
                "date": "2022-10"
            },
            {
                "goals": [
                    {
                        "k": "Budget",
                        "v": 1
                    },
                    {
                        "k": "clean",
                        "v": 2
                    }
                ],
                "date": "2022-8"
            }
        ]
    }
]

// 提取核心数据
const { planDetails, setVisits } = data[0];

// 构建日期到目标值的映射:{ 日期: { 目标名: 数值 } }
const dateGoalMap = setVisits.reduce((map, item) => {
    const goalObj = item.goals.reduce((goalMap, goal) => {
        goalMap[goal.k] = goal.v;
        return goalMap;
    }, {});
    map[item.date] = goalObj;
    return map;
}, {});

// 生成最终数组
const finalArr = planDetails.goals.map(planGoal => {
    const result = {
        goal: planGoal.title,
        frequency: planGoal.frequency
    };
    // 为每个表头日期生成对应的elem字段
    headers.forEach((date, index) => {
        const elemKey = `elem${index + 1}`;
        // 查找当前日期下该目标的数值,无数据则为0
        const count = dateGoalMap[date]?.[planGoal.title] || 0;
        result[elemKey] = { date, count };
    });
    return result;
});

console.log(finalArr);

代码说明

  • dateGoalMap:将分散的setVisits数据聚合为按日期分组的对象,每个日期下存储各目标的完成数,大幅提升查询效率。
  • 遍历计划目标时,通过headers逐个生成elem字段,利用可选链操作符?.安全访问目标数值,无数据时默认填充0。
  • 完全贴合表头顺序生成elem字段,确保和表格列一一对应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:07:22