如何使用TypeScript/Lodash实现数据按序列分组?
按书籍名称分组并整理序列数据
我明白你想要按书籍名称把同一系列的数据聚合起来,把年份和销量整理成嵌套的series数组对吧?这在处理这类结构化数据时很常见,我给你两种常用的JavaScript实现方案:
方法一:使用Array.reduce()(简洁高效的方式)
reduce方法天生适合这种聚合分组的场景,我们可以用它遍历原始数据,逐步构建目标结构:
const originalData = [ {"book": "Typescript 1", "year": "2015", "units": 1000}, {"book": "Javascript 1", "year": "2015", "units": 2000}, {"book": "Typescript 1", "year": "2016", "units": 6000} ]; const groupedData = Object.values(originalData.reduce((acc, item) => { // 检查当前书籍是否已在临时存储中 if (!acc[item.book]) { acc[item.book] = { book: item.book, series: [] }; } // 将年份和销量推入对应书籍的series数组 acc[item.book].series.push({ year: item.year, units: item.units }); return acc; }, {})); console.log(groupedData);
逻辑说明:
- 用
reduce遍历每一条数据,借助临时对象acc存储分组后的中间结果,键为书籍名称,值是目标格式的对象 - 如果当前书籍不在
acc中,就初始化一个包含book字段和空series数组的对象 - 提取当前条目的
year和units,推入对应书籍的series数组 - 最后用
Object.values()把临时对象的取值转换成数组,就是你要的最终结果
方法二:使用普通循环(更直观,适合新手理解)
如果你觉得reduce有点抽象,用for...of循环也能实现同样的效果:
const originalData = [ {"book": "Typescript 1", "year": "2015", "units": 1000}, {"book": "Javascript 1", "year": "2015", "units": 2000}, {"book": "Typescript 1", "year": "2016", "units": 6000} ]; const groupedData = []; const bookMap = {}; for (const item of originalData) { if (!bookMap[item.book]) { const newBookEntry = { book: item.book, series: [] }; groupedData.push(newBookEntry); bookMap[item.book] = newBookEntry; } bookMap[item.book].series.push({ year: item.year, units: item.units }); } console.log(groupedData);
逻辑说明:
- 用
bookMap映射对象跟踪已添加到结果数组的书籍条目,避免重复查找 - 遍历每条数据时,若书籍未在映射中,就创建新的条目并推入结果数组,同时更新映射
- 把当前条目的年份和销量数据推入对应书籍的
series数组
运行任意一段代码,都会得到你预期的输出:
[
{ "book": "Typescript 1", "series": [ {"year": "2015", "units": 1000}, {"year": "2016", "units": 6000} ] },
{ "book": "Javascript 1", "series": [ {"year": "2015", "units": 2000} ] }
]
内容的提问来源于stack exchange,提问作者user1916077
相关产品推荐
相关产品推荐

