
本文介绍如何利用 lodash 的链式操作(或原生 javascript)将形如 `[{ nodes: [...] }, ...]` 的嵌套结构,高效转换为仅包含 `nodes` 数组的二维数组,适用于 graphql 响应数据的标准化处理。
要将原始嵌套结构(外层数组包含多个子数组,每个子数组由 { nodes: [...] } 对象组成)转换为目标结构(外层数组不变,每个子数组内直接存放 nodes 数组),关键在于保留外层数组结构,仅对每一层子数组执行“提取 .nodes 字段”操作。
由于 flatMap 会扁平化层级(例如 flatMap('ciVariables.nodes') 会导致所有 nodes 被压入同一级),它不适用于维持二维结构的场景。此时应选用 map —— 它能精准控制每一层的映射逻辑。
✅ 正确做法是:对外层数组调用 .map(),再对每个子数组内部再次 .map() 提取 nodes 属性:
const result = _.chain(resp.data.data.projects.nodes)
.map(subArray => _.map(subArray, 'nodes')) // 第二层:对每个 { nodes: [...] } 取 nodes
.value();该链式写法等价于原生双层 map:
const result = resp.data.data.projects.nodes.map(arr => arr.map(item => item.nodes) );
⚠️ 注意事项:
- 避免使用 flatMap('ciVariables.nodes') 或 flatMap('nodes'):它们会将所有 nodes 合并为一维数组,破坏原有分组逻辑;
- 若源数据中某些对象可能缺失 nodes 字段,建议添加安全访问:_.map(subArray, item => _.get(item, 'nodes', []));
- 若需兼容空值或非对象项,可结合 _.filter 或 _.compact 进一步清洗。
总结:当目标是结构保持 + 深度字段提取时,优先选择嵌套 map;而 flatMap 仅适用于明确需要降维合并的场景。本例中,双层 map(或 Lodash 链式 .map().map())是最简洁、可读性最强且语义最准确的解决方案。










