如何将特定对象数组按共同键值分组映射为目标数组
嘿,这个数组分组的需求很常见,我给你两种实用的实现方式,都是JavaScript里常用的方法:
方法一:使用Array.prototype.reduce()(最常用简洁)
这是处理这类分组场景的首选方案,利用reduce的累加特性来构建分组结构:
var items = [ {"function":"function_1","process":"process_1"}, {"function":"function_1","process":"process_2"}, {"function":"function_1","process":"process_3"}, {"function":"function_2","process":"process_3"}, {"function":"function_2","process":"process_4"} ]; const result = Object.values(items.reduce((acc, current) => { // 以当前元素的function值作为分组键 const groupKey = current.function; // 如果累加器里还没有这个分组,初始化分组对象 if (!acc[groupKey]) { acc[groupKey] = { function: groupKey, process: [] }; } // 将当前的process值推入对应分组的数组中 acc[groupKey].process.push(current.process); return acc; }, {})); console.log(result);
代码说明:
reduce会遍历数组的每一项,用acc(累加器)临时存储分组后的键值对,键是function的取值。- 每遇到一个元素,先检查累加器中是否存在对应的分组,不存在就创建一个包含
function字段和空process数组的对象。 - 最后用
Object.values()把累加器的对象值转换成你需要的数组格式。
如果要实现你示例中function_1只保留前两个process的效果,只需要在push的时候加个长度判断:
// 仅添加前2个process的过滤逻辑 if (acc[groupKey].process.length < 2) { acc[groupKey].process.push(current.process); }
方法二:使用ES6的Map对象
如果你更喜欢更直观的键值对操作,Map也是个不错的选择:
var items = [ {"function":"function_1","process":"process_1"}, {"function":"function_1","process":"process_2"}, {"function":"function_1","process":"process_3"}, {"function":"function_2","process":"process_3"}, {"function":"function_2","process":"process_4"} ]; const groupMap = new Map(); items.forEach(item => { const groupKey = item.function; // 检查Map中是否已有该分组 if (!groupMap.has(groupKey)) { groupMap.set(groupKey, { function: groupKey, process: [] }); } // 向对应分组的process数组添加元素 groupMap.get(groupKey).process.push(item.process); }); // 将Map的值转换成目标数组 const result = Array.from(groupMap.values()); console.log(result);
代码说明:
Map是ES6新增的键值对集合,用has方法检查分组是否存在,set方法创建新分组,get方法获取分组对象。- 最后用
Array.from(map.values())把Map中的值转换成数组,得到你需要的结构。
内容的提问来源于stack exchange,提问作者madmax80
相关产品推荐
相关产品推荐

