JavaScript如何优雅地将数组元素按title分组并合并data数组?
优雅实现数组转按title分组的对象
嘿,这个需求用JavaScript的Array.prototype.reduce()就能完美解决,它天生就是为这种数组聚合场景设计的,代码简洁又符合函数式编程的优雅风格。
先直接上核心实现代码:
const originalArray = [ {title: 'foo', data: 'something here'}, {title: 'foo', data: 'something else here'}, {title: 'bar', data: 'something else again'} ]; const transformedObject = originalArray.reduce((acc, currentItem) => { // 检查当前title是否已存在,不存在则初始化一个带空data数组的对象 if (!acc[currentItem.title]) { acc[currentItem.title] = { data: [] }; } // 将当前data推入对应title的数组中 acc[currentItem.title].data.push(currentItem.data); return acc; }, {}); console.log(transformedObject); // 输出:{ foo: { data: ['something here', 'something else here'] }, bar: { data: ['something else again'] } }
优化版:更简洁的写法
我们可以用解构赋值直接提取title和data,再用逻辑或简化初始化逻辑,让代码更紧凑:
const transformedObject = originalArray.reduce((acc, { title, data }) => { acc[title] = acc[title] || { data: [] }; acc[title].data.push(data); return acc; }, {});
现代JS风格:用ES2020+语法更严谨
如果你的环境支持ES2020及以上,可以用**逻辑空赋值运算符(??=)**来替代||,它只会在acc[title]为null或undefined时才初始化,避免了||对假值(比如空对象)的误判,逻辑更严谨:
const transformedObject = originalArray.reduce((acc, { title, data }) => { acc[title] ??= { data: [] }; acc[title].data.push(data); return acc; }, {});
为什么说这是优雅的实现?
- 纯函数设计:不会修改原数组,所有操作都基于累加器
acc,副作用最小 - 代码可读性强:reduce的语义清晰,一看就知道是在做数组聚合
- 扩展性好:如果之后需要添加其他字段的合并逻辑,直接在回调里修改即可
内容的提问来源于stack exchange,提问作者Michael Ryan Soileau
相关产品推荐
相关产品推荐

