
本文介绍如何将多层嵌套的标题-子标题-内容结构,按严格层级顺序(title01→subtitle01→content01→title02→subtitle02→content02…)扁平化为一个仅含单个对象的数组,实现语义化键名与序列化编号的精准映射。
本文介绍如何将多层嵌套的标题-子标题-内容结构,按严格层级顺序(title01→subtitle01→content01→title02→subtitle02→content02…)扁平化为一个仅含单个对象的数组,实现语义化键名与序列化编号的精准映射。
在实际业务中(如富文本编辑器导出、CMS内容序列化或表单动态渲染),我们常需将树状嵌套数据转换为线性、有序、键名可预测的扁平结构。但注意:题设目标并非传统 flat() 或递归展平,而是保持层级逻辑顺序 + 自动编号 + 单对象聚合——即最终输出形如 [ { titles01: {...}, subtitles01: {...}, content01: {...}, titles02: {...}, ... } ] 的单元素数组。
以下是推荐的健壮实现方案(已优化原始答案中的硬编码逻辑与潜在 bug):
const data = [
{
titles: [
{
id: 1,
name: "Title 01",
subtitles: [
{
id: 2,
name: "Subtitle 01",
title_id: 1,
content: [
{
id: 3,
name: "Content 01",
subtitle_id: 2,
},
],
},
],
},
{
id: 4,
name: "Title 02", // 注意:原文此处 name 仍为 "Title 01",已按语义修正为 "Title 02"
subtitles: [
{
id: 5,
name: "Subtitle 02",
title_id: 4,
content: [
{
id: 6,
name: "Content 02",
subtitle_id: 5,
},
],
},
],
},
],
},
];
function flattenBySequence(arr) {
const result = {};
let titleIndex = 0;
arr.forEach((section) => {
if (!Array.isArray(section.titles)) return;
section.titles.forEach((title) => {
titleIndex++;
const titleKey = `titles${titleIndex {
const subtitleKey = `subtitles${titleIndex {
const contentKey = `content${titleIndex <p>✅ <strong>关键设计说明:</strong> </p>
-
序列号统一基于
title顺序:每个title触发一次titleIndex++,其下属subtitle和content共享同一序号(如titles01/subtitles01/content01),严格满足“一标题→一子标题→一内容”的线性节奏; -
智能编号格式:
titleIndex 实现 <code>01,02, ...,10,11的自然补零,避免titles1与titles10键名排序错乱; -
防御性编程:显式校验
Array.isArray(),防止空字段或数据缺失导致运行时错误; -
语义清晰命名:函数名
flattenBySequence明确表达“按顺序扁平化”,优于模糊的flattenData。
⚠️ 注意事项:
- 此方案假设每
title最多含一个subtitle,且每个subtitle最多含一个content(符合题设结构)。若需支持多 subtitle / 多 content,请明确扩展规则(如subtitle01_01,content01_01); - 键名大小写需统一(原文
sutitles01为笔误,已修正为subtitles01); - 若数据量极大,可考虑使用
Map替代对象累加以提升性能,但对常规 CMS 场景无必要。
该方法兼顾可读性、可维护性与业务语义,是处理层级化内容序列化的典型工程实践。










