
本文介绍如何将嵌套 json 数据(按日期分组、每组含多类别)通过 react 的 map 方法重构为“类别为行、日期为列”的标准表格,解决原始渲染导致重复行的问题。
在 React 中渲染结构化表格时,若原始数据按时间维度嵌套(如每个日期对象包含多个类别子项),直接双层 map 会生成「日期 × 类别」的笛卡尔积式行结构,导致同一类别重复出现——这正是问题中表格错位的根本原因。要实现「类别为行、日期为列」的转置效果,关键在于先归一化数据,再按类别聚合跨日期值。
✅ 正确的数据预处理流程
首先,将 category_evolution 扁平化为单一数据流,再按 category 分组构建映射表:
// 1. 合并所有日期下的 data 数组
const flatData = category_evolution.flatMap(item => item.data);
// 2. 按 category 归组:{ "Criptomoedas": [...], "REITs": [...], ... }
const categoryMap = flatData.reduce((acc, item) => {
const { category } = item;
if (!acc[category]) acc[category] = [];
acc[category].push(item);
return acc;
}, {});? 推荐使用 flatMap 替代 reduce(...concat),语义更清晰;reduce 初始化为空对象 {},确保类型安全。
✅ 渲染转置表格(JSX)
表头保持原逻辑(日期列),但
需遍历 categoryMap 的每个键(即唯一类别),并在每行中按日期顺序取对应值:| Categoria | {category_evolution.map(({ name }) => ({name} | ))}
|---|---|
| {category} | {/* 按 category_evolution 原始顺序匹配日期,避免错位 */} {category_evolution.map(({ name }) => { const match = entries.find(item => item.date === name); return ({match ? match.category_total_brl : '-'} | ); })}
⚠️ 注意事项与健壮性增强
- 日期顺序一致性:category_evolution 的原始顺序决定了表头和数据列的对应关系,务必确保 item.date 字段与 name 完全一致(如 "01/02/2023"),否则 find() 将返回 undefined。
- 空值容错:使用 match ? ... : '-' 防止某类别在某日期缺失时渲染 undefined。
-
性能优化:若数据量大,可提前构建 dateToIndex 映射,将 find() 改为 O(1) 查找:
const dateIndex = Object.fromEntries( category_evolution.map((item, i) => [item.name, i]) ); // 然后 entries[dateIndex[name]] 即可直接索引
-
可扩展性:如需支持 USD 列,只需复制
并替换 category_total_usd 字段即可。 通过这种「先归一、再分组、最后按序取值」的模式,你不仅能精准实现目标表格结构,还能轻松适配新增日期或类别,真正让 map 成为动态表格的可靠引擎。










