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

JavaScript层级树结构构建求助:双数组数据格式化问题

问题:无法生成指定层级结构的员工树状列表

我需要实现展示员工层级关系的树结构,已有可运行的JavaScript代码,但由于数据来自staffMembers(员工数据)和categories(部门分类)两个独立数组,存在数据匹配和层级渲染的问题,无法生成如下指定格式的层级列表:

<ul>
<li>Terry Cats - Chief Creative Officer: Executive
<ul>
<li>Nick Thompson - Head of Design: Operations
<ul>
<li>Nick Jenson - Intern designer: Interns</li>
</ul>
</li>
</ul>
</li>
<li>Bruce Davids - Chief Strategy Officer: Executive
<ul>
<li>David Smith - Head of Development: Operations</li>
<li>John Jones - Head of Marketing: Operations</li>
</ul>
</li>
<li>Bill Bass - Chief Executive Officer: Executive</li>
</ul>

现有代码

const staffMembers = [
    { 
        "_id" :0, 
        "name" : "David", 
        "surname" : "Smith", 
        "slug": "david-smith",
        "category" : "operations",
        "title": "Head of Development",
        "reportsTo": "bruce-davids"
    },
    { 
        "_id" :1, 
        "name" : "John", 
        "surname" : "Jones", 
        "slug": "john-jones",
        "category" : "operations",
        "title": "Head of Marketing",
        "reportsTo": "bruce-davids"
    },
    { 
        "_id" :3, 
        "name" : "Nick", 
        "surname" : "Thompson", 
        "slug": "nick-thompson",
        "category" : "operations",
        "title": "Head of Design",
        "reportsTo": "terry-cats"
    },
    { 
        "_id" :4, 
        "name" : "Nick", 
        "surname" : "Jenson", 
        "slug": "nick-jenson",
        "category" : "interns",
        "title": "Intern designer",
        "reportsTo": "nick-thompson" 
    },
    { 
        "_id" :6, 
        "name" : "Terry", 
        "surname" : "Cats", 
        "slug": "terry-cats",
        "category" : "c-suite",
        "title": "Chief Creative Officer",
        "reportsTo": "" 
    },
    { 
        "_id" :7, 
        "name" : "Bruce", 
        "surname" : "Davids", 
        "slug": "bruce-davids",
        "category" : "c-suite",
        "title": "Chief Strategy Officer",
        "reportsTo": "" 
    },
    { 
        "_id" :8, 
        "name" : "Bill", 
        "surname" : "Bass", 
        "slug": "bill-bass",
        "category" : "c-suite",
        "title": "Chief Executive Officer",
        "reportsTo": "" 
    }
]

const categories = [
    { 
        "_id" :0, 
        "name" : "Executive", 
        "parent" : "", 
        "slug" : "c-suite" 
    },
    { 
        "_id" :1, 
        "name" : "Operations", 
        "parent" : "c-suite", 
        "slug" : "operations" 
    },
    { 
        "_id" :2, 
        "name" : "Interns", 
        "parent" : "operations", 
        "slug" : "interns" 
    },
];

const hierarchy = (data) => {
    const tree = [];
    const childOf = {};
    let results = [];
        let cat = "";
        let childrens = [];
    data.forEach((item,index) => {
        const { slug, reportsTo, category } = item;
        // console.log(category);
        childOf[slug] = childOf[slug] || [];
        item.children = childOf[slug];
        reportsTo ? (childOf[reportsTo] = childOf[reportsTo] || []).push(item) : tree.push(item);
        // if(category == categories.slug ){
            cat = category;
            const indexs = categories.findIndex(object => {
                return object._id;
            });
        // }
        });
  
  for(let i = 0;i < tree.length;i++){
    for(let j = 0;j < tree[i].children.length;j++){

        childrens = (tree[i].children[j]);
    }
    results.push(tree[i].name + " " + tree[i].surname + " - " + tree[i].title +": " 
    + cat + '*' + childrens.name + " " + childrens.surname + " - " + childrens.title + ": " + "cat"+cat);
  }
    return results;

};

解决方案

现有代码的核心问题:

  1. 未正确将员工的category字段(slug值)映射到categories数组中的显示名称(比如c-suite对应Executive)
  2. 层级渲染逻辑仅处理了一层子节点,无法递归生成多层嵌套结构
  3. 字符串拼接逻辑固定,无法适配动态的员工层级

修正后的代码如下:

// 先创建category的slug到名称的映射,方便快速查找
const categoryMap = categories.reduce((map, cat) => {
    map[cat.slug] = cat.name;
    return map;
}, {});

// 递归生成层级HTML的函数
function generateEmployeeTreeHTML(employees) {
    if (!employees.length) return '';
    
    let html = '<ul>';
    employees.forEach(emp => {
        // 获取员工对应的分类名称
        const categoryName = categoryMap[emp.category] || emp.category;
        // 拼接当前员工的li内容
        html += `<li>${emp.name} ${emp.surname} - ${emp.title}: ${categoryName}`;
        // 如果有子节点,递归生成子节点的HTML
        if (emp.children && emp.children.length) {
            html += generateEmployeeTreeHTML(emp.children);
        }
        html += '</li>';
    });
    html += '</ul>';
    return html;
}

// 主函数:构建员工树状结构并生成HTML
const buildHierarchy = (staffData) => {
    const tree = [];
    const childMap = {};
    
    // 第一步:构建员工的树状结构
    staffData.forEach(emp => {
        // 给每个员工添加children属性
        emp.children = childMap[emp.slug] || [];
        if (emp.reportsTo) {
            // 如果有上级,把当前员工加入上级的children列表
            if (!childMap[emp.reportsTo]) {
                childMap[emp.reportsTo] = [];
            }
            childMap[emp.reportsTo].push(emp);
        } else {
            // 没有上级的是根节点,加入tree数组
            tree.push(emp);
        }
    });
    
    // 第二步:递归生成HTML
    return generateEmployeeTreeHTML(tree);
};

// 调用函数生成HTML并插入页面(示例)
const hierarchyHTML = buildHierarchy(staffMembers);
console.log(hierarchyHTML);
// 如果要插入到页面,可以用 document.getElementById('container').innerHTML = hierarchyHTML;

代码说明

  1. categoryMap:通过reduce方法把categories数组转换成键值对,键是slug,值是分类名称,这样可以O(1)时间获取员工对应的分类显示名。
  2. generateEmployeeTreeHTML:递归函数,接收员工数组,生成对应的<ul>和<li>结构,遇到有子节点的员工时,递归调用自身生成子层级。
  3. buildHierarchy:先遍历员工数据,构建出带有children属性的树状结构,根节点是没有reportsTo的员工,然后调用递归函数生成完整的HTML。

运行修正后的代码,就能生成你需要的层级列表结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:35:41