30 seconds of code:使用递归扁平化(Flatten)与还原(Unflatten)JavaScript 嵌套对象
教程文档【免费下载链接】30-seconds-of-codeCoding articles to level up your development skills项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-code点击查看免费下载对象是 JavaScript 中最常用的数据结构之一但在不同场景下数据往往需要以不同的形态呈现有时你需要把深层嵌套的对象「拍平」成带路径分隔符的扁平键值对例如用于序列化、存储或表格展示有时又需要把扁平数据还原回嵌套结构。本指南基于 30 seconds of code 仓库的 JavaScript 片段 flatten-unflatten-object.md完整讲解基于递归策略实现对象扁平化与还原的算法思路、完整可运行代码、分隔符定制技巧以及关键 APIObject.keys()、Array.prototype.reduce()、Object.assign()、String.prototype.split()的底层配合方式读完即可在自己的项目中直接复制使用。为什么需要扁平化对象数据形态的转换场景数据表示形式往往各不相同对数据结构的需求也因场景而异。例如存储与序列化某些存储引擎如 Key-Value 数据库、表格视图需要扁平的键值对而嵌套对象无法直接落库配置与表单处理表单提交的数据常以user.address.city这类路径式键名传递需要先拍平再处理日志与监控将嵌套指标拍平为src.styles.main这样的键便于统一索引和检索。在这类需求中将嵌套对象转换为扁平对象或反向还原是非平凡的任务但可以借助递归策略优雅地解决。该片段被收录在 object.yaml 的 JavaScript 对象文章集合中标签为object与recursion是递归处理对象结构的典型范例。扁平化对象将每个叶节点转换为带前缀的路径节点给定一个嵌套对象扁平化的核心思路是将每一个「叶子节点」转换为一个「带完整路径前缀的扁平节点」。为便于理解先看一个实际例子——一个描述文件大小的嵌套对象const fileSizes { package: 256, src: { index: 1024, styles: { main: 128, colors: 16 }, }, assets: { images: { logo: 512, background: 512 }, fonts: { serif: 64 } } };扁平化之后得到的是以.作为路径分隔符的扁平对象const flattenedFileSizes { package: 256, src.index: 1024, src.styles.main: 128, src.styles.colors: 16, assets.images.logo: 512, assets.images.background: 512, assets.fonts.serif: 64 };[!NOTE]结果键的顺序可能与原始键的顺序不一致因为 JavaScript对象本身是无序的。本文所有示例为便于理解均保留了原始顺序。递归的基线条件Base Case构建递归解决方案的第一步是定义基线条件。在此场景下基线条件是值为非对象的键此时可以直接将该键值对加入结果对象。而对于值为对象的键则需要递归调用函数本身并把当前键作为前缀附加到子键上在更深层级时还必须把此前累积的所有前缀都拼接到当前键前面。按照这一算法就能逐步构建出完整的扁平化对象。JavaScript 实现reduce Object.assign 的组合在 JavaScript 中落地时可以使用Object.keys()获取对象的所有键配合Array.prototype.reduce()将每个叶子节点转换为扁平路径节点若某键的值是对象则以合适的前缀递归调用函数并通过Object.assign()把递归结果合并进累积器否则直接把「带前缀的键 → 值」加入累积器对象。完整代码如下const flattenObject (obj, delimiter ., prefix ) Object.keys(obj).reduce((acc, k) { const pre prefix.length ? ${prefix}${delimiter} : ; if ( typeof obj[k] object obj[k] ! null Object.keys(obj[k]).length 0 ) Object.assign(acc, flattenObject(obj[k], delimiter, pre k)); else acc[pre k] obj[k]; return acc; }, {});三个关键设计细节这段代码虽然短小但包含了几个容易忽略的细节值得逐一拆解空对象必须当作叶子节点条件中的Object.keys(obj[k]).length 0确保空对象{}不会被继续递归而是作为普通值直接写入结果。若不处理这一点空对象会递归出「无键」的结果造成信息丢失。null必须显式排除typeof null object因此必须用obj[k] ! null把null视为叶子值否则会出现对null调用Object.keys()的运行时错误。前缀只在非空时拼接分隔符const pre prefix.length ?${prefix}${delimiter}: 保证顶层键不带多余的前缀分隔符而深层键会拼接为prefix delimiter key的形式。自定义分隔符上面的示例默认使用.作为键的分隔符但通过额外的参数即可自由定制比如改为路径风格的分隔符/// 沿用前面的 fileSizes 对象 flattenObject(fileSizes, /); /* { package: 256, src/index: 1024, src/styles/main: 128, src/styles/colors: 16, assets/images/logo: 512, assets/images/background: 512, assets/fonts/serif: 64 } */需要注意最后一个参数prefix仅供递归调用使用除非你希望每个键都带一个全局前缀例如在多个对象合并到同一命名空间时否则正常调用时应省略该参数传入任何值都会让所有键被统一加上此前缀。还原对象沿路径逐级重建嵌套结构反向操作——unflatten还原——的思路略有不同给定扁平对象中的某个键你需要以分隔符拆分路径再用拆分得到的数组逐级创建嵌套对象。实现上依赖String.prototype.split()将键按分隔符拆分为路径片段数组再用Array.prototype.reduce()沿路径逐步向下构建。reduce 的累积逻辑是若当前累积器当前层级的对象中已经存在该键对应的值则直接返回该值作为下一层累积器说明该分支已存在可继续向下延伸否则在累积器中添加对应的键值对再返回该值作为下一层累积器。此外代码还利用isNaN(Number(keys[i 1]))做了一个巧妙处理当下一个路径片段是数字时用数组[]而非对象{}作为新层级的容器从而兼容数组索引类型的路径键。最后通过Object.keys()与Array.prototype.reduce()对扁平对象中的每一个键应用上述过程const unflattenObject (obj, delimiter .) Object.keys(obj).reduce((res, k) { k.split(delimiter).reduce( (acc, e, i, keys) acc[e] || (acc[e] isNaN(Number(keys[i 1])) ? keys.length - 1 i ? obj[k] : {} : []), res ); return res; }, {});还原前文flattenedFileSizes对象即可得到与原始fileSizes完全一致的嵌套结构unflattenObject(flattenedFileSizes); /* { package: 256, src: { index: 1024, styles: { main: 128, colors: 16 }, }, assets: { images: { logo: 512, background: 512 }, fonts: { serif: 64 } } } */还原算法的实现要点表达式求值而非语句赋值内层 reduce 的回调使用acc[e] || (acc[e] ...)的短路写法既完成了「已存在则复用」的判断又完成了「不存在则创建」的赋值一行代码同时承担了查重、建分支、向下传递三层职责。叶节点定位keys.length - 1 i判断当前是否为路径的最后一段若是则将原始扁平值obj[k]写入该位置否则先创建一个空容器{}或[]继续下钻。数组分支支持isNaN(Number(keys[i 1]))用于探测下一段路径是否为纯数字字符串从而用数组承接数字索引路径例如还原形如list.0.name的键时会生成数组分支。使用边界与数据丢失警告[!WARNING]扁平化与还原对象可能造成数据丢失尤其是当键本身包含分隔符时。例如原始对象中同时存在{a.b: 1, a: {b: 2}}这样两个键时扁平化后都会产生a.b后者会覆盖前者且无法再被准确还原。在处理和转换数据时务必谨慎。除此之外还有几个实践中的边界情况值得留意数组与嵌套对象的混合扁平化时数组会被当作「非空对象」递归展开typeof [] object生成的键形如items.0.name还原时虽有数组分支支持但空数组[]由于Object.keys([]).length 0会被当作叶子值直接保留行为与预期一致。分隔符冲突若数据中的键本身包含.、/等分隔符务必选用原始数据中不可能出现的字符作为分隔符否则扁平化与还原将不可逆。__proto__、constructor等特殊键还原过程会向对象写入任意路径键若扁平键包含原型链相关的特殊名称可能引发意外行为在不可信数据上使用时应格外小心。从仓库源码看该片段的定位与配套从仓库结构可以进一步确认该片段的定位与使用方式片段源文件位于 flatten-unflatten-object.mdfrontmatter 声明了tags: [object, recursion]、language: javascript被收录进 JavaScript 对象文章集合 object.yamltagMatcher: object与仓库中其他对象处理类片段构成同一知识体系仓库中与之互补的递归题材片段 flat-iterator.md 展示了另一类「拍平」——用生成器函数 yield*递归扁平化嵌套可迭代对象数组、Set 等如果你面对的是嵌套集合而非键值对象可以参考该片段redirects.yaml 中记录了该片段的历史跳转映射to: /js/s/flatten-unflatten-object说明该片段在站点路由中拥有稳定的公开地址可直接引用。如果你需要查看该片段在实际网站中的渲染效果可通过仓库的构建配置astro.config.mjs与内容加载器loader.js了解片段到页面的转换流程而Object.keys()、reduce等 API 在仓库的 ES6 辅助函数体系中也被大量复用可作为进阶学习的参照。小结对象扁平化与还原是一对典型的递归算法应用扁平化以「值为非对象」为基线条件逐层拼接路径前缀将嵌套对象压缩为路径式键值对还原则以分隔符拆分路径、逐级重建嵌套容器并在检测到数字路径片段时自动使用数组。两者都以Object.keys()Array.prototype.reduce()为骨架配合Object.assign()与String.prototype.split()完成数据搬运。核心代码均可在 flatten-unflatten-object.md 中直接取用唯一需要牢记的是当键中包含分隔符时转换可能不可逆请务必根据实际数据谨慎选择分隔符并做好数据校验。赞分享教程文档【免费下载链接】30-seconds-of-codeCoding articles to level up your development skills项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-code点击查看免费下载相关推荐Rofi 缩略图系统rofi-thumbnails完全指南XDG Thumbnailer、thumbnail:// 协议与 -preview-cmd 自定义预览Rofi 缩略图系统rofi thumbnails完全指南XDG Thumbnailer、 thumbnail:// 协议与 preview cmd 自定教程文档30 seconds of code用 JavaScript Proxy 实现不可变对象30 seconds of code用 JavaScript Proxy 实现不可变对象 对象可变性Object mutability与 const 关键教程文档30 seconds of code 深度解读JavaScript 到底是按值传递还是按引用传递30 seconds of code 深度解读JavaScript 到底是按值传递还是按引用传递 导读 在 JavaScript 开发中函数参数究竟如何教程文档创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

文档感知模式实战:用claudex-loop的CONTEXT.md术语表与ADR沉淀项目决策

文档感知模式实战:用claudex-loop的CONTEXT.md术语表与ADR沉淀项目决策

文档感知模式实战:用claudex-loop的CONTEXT.md术语表与ADR沉淀项目决策 【免费下载链接】claudex-loop Claude Code skill: four-phase plan hardening (recon, interrogate, Codex adversarial review, cross-model build & inspection) — two AI models hard…

2026/10/4 8:55:59 阅读更多 →
AI Agent对云架构的挑战:计算、推理与数据如何重构

AI Agent对云架构的挑战:计算、推理与数据如何重构

1. 传统云架构为什么在 Agent 面前突然不够用了先说我自己的经历。去年年底,我接了一个项目,给一家做电商客服的公司搭一套 AI Agent 系统。当时我脑子里还是过去做微服务的那套思路:前端请求进来,负载均衡分发给后端服务&#xf…

2026/10/4 8:55:59 阅读更多 →
零基础用Codex接外包:半天完成代码单月入几千的实操路径

零基础用Codex接外包:半天完成代码单月入几千的实操路径

1. 从标题拆解:一个外包接单的真实路径“靠Codex半天写完外包,零基础也能接代码单月入几千”——这个标题我第一次看到的时候,第一反应不是“吹牛”,而是“这事有戏,但前提得说清楚”。Codex这类AI编程助手&#xff0c…

2026/10/4 8:55:59 阅读更多 →

最新新闻

BranchIP:自适应等变计算驱动的原子间势能建模新范式

BranchIP:自适应等变计算驱动的原子间势能建模新范式

1. 项目概述:为什么“自适应等变计算”正在重构原子间势能建模的底层逻辑BranchIP这个名字乍看像某个冷门开源库的代号,但拆开来看——Branch(分支)、IP(Interatomic Potential,原子间势能)——…

2026/10/5 13:59:21 阅读更多 →
自己动手,三分之一预算:开源驾驶舱openrig铝型材DIY全攻略

自己动手,三分之一预算:开源驾驶舱openrig铝型材DIY全攻略

你有没有算过一笔账:一套像样的模拟赛车驾驶舱,成品买下来普遍要8000到20000元,好一点的直接奔着5万去了。但如果自己动手,用开源图纸和铝型材拼一台,成本可以压到三分之一以下,刚性还不输成品。这就是open…

2026/10/5 13:59:21 阅读更多 →
OpenRig开源开放式机架:从设计到组装,打造高效散热DIY工作站

OpenRig开源开放式机架:从设计到组装,打造高效散热DIY工作站

OpenRig 这名字拆开看就是 Open Rig,开放式机架。我做这个项目从画第一张草图到实机点亮,前后折腾了两个多月,期间推翻了三次结构方案,废掉一版亚克力切割件,最后才定下来现在这套既兼顾散热、又方便维护、还能随意扩…

2026/10/5 13:59:21 阅读更多 →
CARM:LLM强化学习中取消响应的精准掩码方案

CARM:LLM强化学习中取消响应的精准掩码方案

1. 项目概述:为什么在LLM强化学习中,“取消响应”会成为训练灾难的隐形推手?最近在做几个数学推理和代码生成类任务的RLHF微调时,我反复遇到一个特别诡异的现象:模型明明在监督微调(SFT)阶段表现…

2026/10/5 13:59:21 阅读更多 →
OpenShell实战:让大模型通过自然语言驱动本地Shell执行代码

OpenShell实战:让大模型通过自然语言驱动本地Shell执行代码

1. 项目概述1.1 它到底是什么OpenShell这个名字,乍一听像是个终端模拟器,或者某个开源Shell的变体。但实际上,它做的事比“Shell”这两个字所暗示的要大得多——它是一套把自然语言转换成可执行代码,并在本地环境中直接运行的开源…

2026/10/5 13:59:21 阅读更多 →
落地页文案的10个转化技巧:用ai-design-skills写好标题公式与CTA

落地页文案的10个转化技巧:用ai-design-skills写好标题公式与CTA

落地页文案的10个转化技巧:用ai-design-skills写好标题公式与CTA 【免费下载链接】ai-design-skills 项目地址: https://gitcode.com/gh_mirrors/ai/ai-design-skills ai-design-skills 是一套面向 Claude Code、Cursor 等 AI 编程工具的落地页设计技能库&a…

2026/10/5 13:58:20 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:40:45 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 20:14:29 阅读更多 →