JavaScript实现JSON数组按id分组转换为指定格式
按id分组并转换为目标格式的实现方案
你的两个现有实现核心分组逻辑都是正确的,仅输出格式和预期要求存在差异:预期输出是由单键对象组成的数组,你当前拿到的是分组后的普通键值对对象,只需要补充一步格式转换即可。两种实现的时间复杂度均为O(n),完全可以支撑大数据量场景。
原生JS实现(无依赖,性能最优,推荐大数据量场景使用)
基于你已写的Array.reduce逻辑调整,仅在分组完成后增加格式转换步骤,整体仅做2轮极轻量遍历:
const groupByIdToTargetFormat = (arr) => { // 按id分组收集对应sid,逻辑和你原有实现一致 const sidGroupMap = arr.reduce((collector, currentItem) => { if (!collector[currentItem.id]) { collector[currentItem.id] = [] } collector[currentItem.id].push(currentItem.sid) return collector }, {}) // 将分组对象转换为要求的单键对象数组格式 return Object.entries(sidGroupMap).map(([id, sidList]) => ({ [id]: sidList })) } // 调用测试 const testInput = [ { "id": "11111", "sid": "12345" }, { "id": "22222", "sid": "23456" }, { "id": "22222", "sid": "34567" } ] console.log(groupByIdToTargetFormat(testInput)) // 输出和你给出的预期结果完全一致
性能说明:该实现第一轮遍历原数组完成分组,第二轮仅遍历不重复的id值做格式转换,总遍历次数远小于2倍原数组长度,十万级以上数据量运行也不会有卡顿。
Lodash实现版本
基于你已写的_.groupBy逻辑调整,补充sid提取和格式转换步骤即可:
import _ from 'lodash' const testInput = [ { "id": "11111", "sid": "12345" }, { "id": "22222", "sid": "23456" }, { "id": "22222", "sid": "34567" } ] const result = _.chain(testInput) .groupBy('id') // 按id字段分组 .mapValues(idGroup => _.map(idGroup, 'sid')) // 提取每个分组下的所有sid值,替换原有完整对象 .toPairs() // 转换为[id, sid数组]格式的二维数组 .map(([id, sidList]) => ({ [id]: sidList })) // 组装为要求的单键对象 .value() console.log(result)
如果项目中已经全局引入lodash可以直接用这个写法,否则优先选原生实现,减少依赖开销。
内容的提问来源于stack exchange,提问作者stackofnoob
相关产品推荐
相关产品推荐

