JavaScript对象数组分组排序逻辑求助:按type集合分组并去重name
实现方案
步骤拆解
- 按name聚合type:把原数组中同一个name对应的所有type收集到一起,为后续处理做准备。
- 排序并拼接type:对每个name的type数组按数字大小排序,再用
-拼接成唯一的分组标识。 - 去重type分组:确保每个type分组只对应一个name(保留第一个出现的name)。
- 转换为目标数组:把最终的分组对象转换为要求的数组格式。
代码实现
const test = [ {name: 'a', type: '1'}, {name: 'a', type: '2'}, {name: 'a', type: '3'}, {name: 'b', type: '1'}, {name: 'b', type: '2'}, {name: 'c', type: '3'}, {name: 'd', type: '1'}, {name: 'e', type: '4'}, {name: 'e', type: '3'}, {name: 'f', type: '1'}, {name: 'f', type: '2'}, {name: 'f', type: '3'}, {name: 'g', type: '2'}, ]; // 1. 按name聚合type const nameTypeMap = {}; test.forEach(item => { if (!nameTypeMap[item.name]) { nameTypeMap[item.name] = []; } nameTypeMap[item.name].push(item.type); }); // 2. 处理type并构建分组去重 const typeNameMap = {}; Object.entries(nameTypeMap).forEach(([name, types]) => { // 按数字排序type,避免字符串排序的异常问题 const sortedTypes = types.sort((a, b) => Number(a) - Number(b)); const typeKey = sortedTypes.join('-'); // 仅保留第一个匹配该type分组的name if (!typeNameMap[typeKey]) { typeNameMap[typeKey] = name; } }); // 3. 转换为目标数组格式 const clean = Object.entries(typeNameMap).map(([type, names]) => ({ type, names })); console.log(clean);
代码说明
- 第一步通过
forEach遍历原数组,生成nameTypeMap,结构示例:{a: ['1','2','3'], b: ['1','2'], ...}。 - 第二步遍历
nameTypeMap,对type数组做数字排序(避免'10'排在'2'前面的字符串排序错误),拼接成typeKey后存入typeNameMap,保证同一个分组标识只对应第一个出现的name。 - 最后将
typeNameMap的键值对转换为目标数组,得到符合要求的结果。
内容的提问来源于stack exchange,提问作者Mayga Fatmawati
相关产品推荐
相关产品推荐

