如何对对象数组排序:确保父ID对应对象排在子对象之前
需求:按父节点优先规则排序对象数组
现有数组
let arrOfObjs = [ { "id": "unique1", "parentId": "unique3", // 等于arrOfObjs[2].id "title": "title1" }, { "id": "unique2", "parentId": "unique3", // 同样等于arrOfObjs[2].id "title": "title2" }, { "id": "unique3", "parentId": "", "title": "title3" } ]
已知条件
- id始终唯一
- parentId对应数组中某一对象的id,允许重复
排序目标
确保父对象(id被其他对象的parentId引用)始终排在所有子对象之前。示例中unique3作为父节点,需排在unique1和unique2前面,最终期望结果:
let arrOfObjs = [ { "id": "unique3", "parentId": "", "title": "title3" }, { "id": "unique2", "parentId": "unique3", "title": "title2" }, { "id": "unique1", "parentId": "unique3", "title": "title1" } ]
实现方案
方法一:依赖映射+自定义排序
适合简单层级场景,通过快速映射和排序函数直接调整顺序:
- 先构建id到对象的映射表,避免重复遍历数组查找父节点
- 自定义排序逻辑,直接对比两个对象的父子关系,同时处理多层嵌套的层级对比
// 构建id到对象的映射 const idMap = arrOfObjs.reduce((map, obj) => { map[obj.id] = obj; return map; }, {}); // 执行排序 arrOfObjs.sort((a, b) => { // 若b的父节点是a,a优先排前 if (b.parentId === a.id) return -1; // 若a的父节点是b,b优先排前 if (a.parentId === b.id) return 1; // 处理多层嵌套:获取节点的顶层父节点层级 const getTopLevel = (obj, level = 0) => { if (!obj.parentId) return level; return getTopLevel(idMap[obj.parentId], level + 1); }; const levelA = getTopLevel(a); const levelB = getTopLevel(b); // 层级越小(越顶层)排越前 return levelA - levelB; });
方法二:拓扑排序
适合复杂多层嵌套场景,能彻底解决所有依赖顺序问题,确保所有父节点都排在子节点之前:
- 构建节点的子节点列表和入度统计(入度表示该节点有多少父依赖)
- 从根节点(无parentId)开始,依次处理节点并减少子节点的入度,入度为0时说明该节点的所有父节点已处理完成,可加入结果
const sortByParentPriority = (arr) => { const idMap = {}; const childrenMap = {}; const inDegree = {}; // 初始化映射结构 arr.forEach(obj => { idMap[obj.id] = obj; childrenMap[obj.id] = childrenMap[obj.id] || []; inDegree[obj.id] = inDegree[obj.id] || 0; if (obj.parentId) { childrenMap[obj.parentId].push(obj.id); inDegree[obj.id]++; } }); // 初始化队列:所有根节点(无父节点) const queue = arr.filter(obj => !obj.parentId).map(obj => obj.id); const result = []; while (queue.length) { const currentId = queue.shift(); result.push(idMap[currentId]); // 处理当前节点的所有子节点,入度减1,入度为0则加入队列 childrenMap[currentId].forEach(childId => { inDegree[childId]--; if (inDegree[childId] === 0) queue.push(childId); }); } return result; }; // 使用示例 const sortedArr = sortByParentPriority(arrOfObjs); console.log(sortedArr);
内容的提问来源于stack exchange,提问作者Orneslat
相关产品推荐
相关产品推荐

