如何用TypeScript将重复用户记录转换为嵌套数组结构?
TypeScript 实现用户课程记录合并优化方案
需求说明
原始数据中每条记录对应一个用户的一门课程,存在重复的用户信息:
id name courseId title 1 user 1 11 course A 1 user 1 22 course B 2 user 2 33 course C 3 user 3 44 course D
需要将同一用户的课程合并为数组,得到如下结构:
[ { "id": 1, "name": "user 1", "courses": [ { "courseId": 11, "title": "course A" }, { "courseId": 22, "title": "course B" } ] }, { "id": 2, "name": "user 2", "courses": [ { "courseId": 33, "title": "course C" } ] }, { "id": 3, "name": "user 3", "courses": [ { "courseId": 44, "title": "course D" } ] } ]
实现步骤
1. 定义类型接口
先明确原始数据和目标数据的类型,保证TypeScript的类型安全:
// 原始用户课程记录类型 interface RawUserCourse { id: number; name: string; courseId: number; title: string; } // 合并后的用户类型 interface MergedUser { id: number; name: string; courses: Array<{ courseId: number; title: string }>; }
2. 编写合并函数
用Array.reduce遍历处理,借助临时对象缓存已处理的用户,时间复杂度为O(n),是高效的实现方式:
function mergeUserCourses(rawData: RawUserCourse[]): MergedUser[] { // 用对象缓存用户,key为用户id,value为合并后的用户对象 const userMap = rawData.reduce((acc, item) => { // 用户已存在,直接添加课程 if (acc[item.id]) { acc[item.id].courses.push({ courseId: item.courseId, title: item.title }); } else { // 用户不存在,创建新对象并初始化课程数组 acc[item.id] = { id: item.id, name: item.name, courses: [{ courseId: item.courseId, title: item.title }] }; } return acc; }, {} as Record<number, MergedUser>); // 将对象的值转为数组,得到最终结果 return Object.values(userMap); }
3. 示例使用
// 原始数据 const rawData: RawUserCourse[] = [ { id: 1, name: "user 1", courseId: 11, title: "course A" }, { id: 1, name: "user 1", courseId: 22, title: "course B" }, { id: 2, name: "user 2", courseId: 33, title: "course C" }, { id: 3, name: "user 3", courseId: 44, title: "course D" } ]; // 调用函数得到合并结果 const mergedResult = mergeUserCourses(rawData); console.log(mergedResult);
说明
这个实现只需要遍历一次原始数组,效率优异;同时通过TypeScript的类型定义,能在编译阶段发现数据结构问题,避免运行时错误。
内容的提问来源于stack exchange,提问作者StormTrooper
相关产品推荐
相关产品推荐

