如何在Node.js中将同名对象合并并转为值为唯一字符串数组的结构?
问题:合并数组中同名对象并转换值为字符串数组
原始对象数组:
const arr = [ { "name": "Day", "value": "Monday" }, { "name": "Month", "value": "November" }, { "name": "Day", "value": "Monday" }, { "name": "Month", "value": "December" }, { "name": "Day", "value": "Friday" }, { "name": "Month", "value": "November" }, { "name": "Day", "value": "Friday" }, { "name": "Month", "value": "December" } ]
需要转换为如下结构:
const final = [ { "name": "Day", "values": [ "Monday", "Friday" ] }, { "name": "Month", "values": [ "November", "December" ] } ]
目前已通过以下代码过滤掉重复的name+value组合:
const filtered = arr.filter( (v, i, a) => a.findIndex(v2 => v?.name === v2?.name && v?.value === v2?.value) === i );
但在合并同名对象并将值转为数组时遇到问题,尝试用Object.assign()的实现无效:
const test = filtered.map(({ name, value }) => Object.assign({ name, value: [] }, (name, value)) ); console.log(test)
解决方案
高效实现:一次遍历完成分组与去重
直接使用reduce遍历原始数组,借助临时对象分组,同时完成去重,时间复杂度为O(n):
const result = Object.values(arr.reduce((acc, { name, value }) => { // 初始化当前name对应的对象结构 if (!acc[name]) { acc[name] = { name, values: [] }; } // 避免values中出现重复值 if (!acc[name].values.includes(value)) { acc[name].values.push(value); } return acc; }, {}));
基于已过滤数组的实现
如果已经有了去重后的filtered数组,可以简化逻辑(无需再次检查重复):
const result = Object.values(filtered.reduce((acc, { name, value }) => { if (!acc[name]) { acc[name] = { name, values: [] }; } acc[name].values.push(value); return acc; }, {}));
为什么你的Object.assign()写法无效
map方法是一对一转换数组元素,无法实现同名对象的聚合合并。而reduce可以通过累加器(临时对象)将相同name的元素聚合到一起,最终再转换为目标数组结构。
内容的提问来源于stack exchange,提问作者GʀᴜᴍᴘʏCᴀᴛ
相关产品推荐
相关产品推荐

