You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS对象数组排序求助:按层级及type规则排序

解决JS对象数组层级排序问题

核心思路

要实现这种层级+类型优先的排序,关键是先建立元素的快速索引,再通过递归处理每个父元素的子元素,同时兼顾类型排序和层级嵌套顺序:

  • 第一步:用对象建立id到元素的映射,这样能O(1)时间找到任意id对应的子元素集合
  • 第二步:写一个递归处理函数,对同一父元素的子元素先按type排序(child优先于block),然后遍历子元素时,遇到block类型就递归插入它的子元素
  • 第三步:从顶层元素(parentId: 0o0000)开始启动递归,生成最终数组

代码实现

// 模拟原数组(示例结构)
const arr = [
  { id: 'block1', parentId: '0o0000', type: 'block' },
  { id: 'child1', parentId: '0o0000', type: 'child' },
  { id: 'child2', parentId: 'block1', type: 'child' },
  { id: 'block2', parentId: 'block1', type: 'block' },
  { id: 'child3', parentId: 'block2', type: 'child' },
];

function sortHierarchy(arr, rootParentId) {
  // 1. 构建id映射和子元素分组
  const idMap = {};
  const childrenMap = {};
  arr.forEach(item => {
    idMap[item.id] = item;
    if (!childrenMap[item.parentId]) {
      childrenMap[item.parentId] = [];
    }
    childrenMap[item.parentId].push(item);
  });

  // 2. 递归处理函数
  function processChildren(parentId) {
    const result = [];
    // 无对应子元素直接返回空数组
    if (!childrenMap[parentId]) return result;
    
    // 先按类型排序:child在前,block在后
    const sortedChildren = [...childrenMap[parentId]].sort((a, b) => {
      if (a.type === 'child' && b.type !== 'child') return -1;
      if (a.type !== 'child' && b.type === 'child') return 1;
      return 0;
    });

    // 遍历排序后的子元素,block类型要递归插入自己的子元素
    sortedChildren.forEach(item => {
      result.push(item);
      if (item.type === 'block') {
        result.push(...processChildren(item.id));
      }
    });

    return result;
  }

  // 3. 从顶层元素开始处理
  return processChildren(rootParentId);
}

// 执行排序,得到目标数组
const newArr = sortHierarchy(arr, '0o0000');
console.log(newArr);

代码说明

  • 映射表idMap和childrenMap避免了反复遍历原数组,提升了效率
  • 排序逻辑里先确保同层级下child类型优先,再处理block的子元素嵌套
  • 递归函数自动处理多层嵌套的block元素,不会丢失层级顺序

内容的提问来源于stack exchange,提问作者Tiltmode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:32:47