处理嵌套的用户数据时,我们常常会遇到一个经典场景:原始数据里,每个人的“角色”信息可能是一个数组,也可能没有。最终,我们需要一份干净、统一的一维列表——如果一个人有多个角色,就为每个角色生成一条独立记录;如果没有角色,则只保留这个人的基本信息。今天,我们就来聊聊如何高效、健壮地实现这个“扁平化”过程,并对比两种主流方案的性能差异。

很多开发者第一反应会使用 map 方法,但很快就会发现一个问题:map 处理后的结果,是一个混合了数组和对象的“不规则结构”,并没有真正实现“扁平化”。问题的核心在于,我们需要将所有结果项都归并到同一个层级的一维数组中。
✅ 推荐方案:reduce + forEach(高性能、语义清晰)
一个兼顾性能与可读性的方案是使用 reduce 配合 forEach。它的思路非常直接:初始化一个空数组作为累加器,然后遍历每个人,根据其角瑟情况,向累加器中推入格式化后的对象。
const cleanRoles = (data) => {
return data.reduce((acc, { name, roles }) => {
if (Array.isArray(roles) && roles.length > 0) {
roles.forEach(({ name: roleName }) => {
acc.push({ name, role: roleName });
});
} else {
acc.push({ name });
}
return acc;
}, []);
};
这个写法有几个优点:
- 语义清晰:
reduce的“累积”概念完美契合“合并到单一数组”的需求。 - 内存友好:直接在累加器数组上操作,避免了创建大量中间数组。
- 性能优异:基准测试表明,在处理大规模数据时,这种方法的性能通常优于其他方案。
