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

科目表转树形结构:代码错误排查及正确实现方案

会计科目表树形结构构建问题排查与修复

问题说明

我有一段表示会计科目表的字符串,期望将其转换为指定的层级树形结构,但自行编写的createChartOfAccountsTree函数无法正确构建父子关系,需要排查代码错误并提供正确实现方案。

原始科目表字符串

1: Comptes de capitaux
10. Capital et Réserves.
101. Capital.
1011. Capital souscrit - non appelé.
1012. Capital souscrit - appelé, non versé.
1013. Capital souscrit - appelé, versé.
10131. Capital non amorti.
10132. Capital amorti.
1018. Capital souscrit soumis à une réglementation particulière.
105. Ecarts de réévaluation.
108. Compte de l'exploitant.

期望输出结构

{
  "1": {
    id: "1",
    accountName: "Comptes de capitaux",
    children: {
      "10": {
        id: "10",
        accountName: "Capital et Réserves",
        children: {
          "101": {
            id: "101",
            accountName: "Capital",
            children: {
              "1011": { id: "1011", accountName: "Capital souscrit - non appelé", children: {} },
              "1012": { id: "1012", accountName: "Capital souscrit - appelé, non versé", children: {} },
              "1013": {
                id: "1013",
                accountName: "Capital souscrit - appelé, versé",
                children: {
                  "10131": { id: "10131", accountName: "Capital non amorti", children: {} },
                  "10132": { id: "10132", accountName: "Capital amorti", children: {} }
                }
              },
              "1018": { id: "1018", accountName: "Capital souscrit soumis à une réglementation particulière", children: {} }
            }
          },
          "105": { id: "105", accountName: "Ecarts de réévaluation", children: {} },
          "108": { id: "108", accountName: "Compte de l'exploitant", children: {} }
        }
      }
    }
  }
}

错误代码问题排查

原函数存在以下几个关键错误:

  • ID提取错误:直接用空格分割行,会把带标点的内容(如1:、10.)当成ID,导致后续父ID计算完全错误。
  • 字符串替换语法错误:accountName.replace(".","",)多了一个多余的逗号,属于语法错误,会导致函数执行失败。
  • 名称清理不彻底:仅替换第一个.,无法清除科目名称末尾的.,也没处理名称前后的多余空格。
  • 父节点判断逻辑脆弱:依赖accounts对象直接查找父ID,但如果ID提取错误,父ID必然不存在,导致所有节点都被当成顶级节点。

正确实现方案

以下是修复后的函数,通过正则匹配准确提取ID和名称,正确构建父子层级:

function createChartOfAccountsTree(input) {
  const accounts = {};
  // 按行分割,过滤空行并去除每行前后空格
  const lines = input.split("\n").map(line => line.trim()).filter(line => line);

  lines.forEach(line => {
    // 用正则匹配ID(开头的数字)、分隔符(:或.)、科目名称
    const match = line.match(/^(\d+)[.:]\s*(.*?)\.?\s*$/);
    if (!match) return;

    const id = match[1];
    const accountName = match[2].trim();
    const account = { id, accountName, children: {} };

    // 存入全局索引
    accounts[id] = account;

    // 计算父ID:长度大于1时取前length-1位
    if (id.length > 1) {
      const parentId = id.slice(0, -1);
      const parent = accounts[parentId];
      if (parent) {
        parent.children[id] = account;
      }
    }
  });

  // 返回顶级节点(ID长度为1的节点)
  return Object.values(accounts).filter(item => item.id.length === 1).reduce((acc, item) => {
    acc[item.id] = item;
    return acc;
  }, {});
}

// 测试调用
const input = `1: Comptes de capitaux
10. Capital et Réserves.
101. Capital.
1011. Capital souscrit - non appelé.
1012. Capital souscrit - appelé, non versé.
1013. Capital souscrit - appelé, versé.
10131. Capital non amorti.
10132. Capital amorti.
1018. Capital souscrit soumis à une réglementation particulière.
105. Ecarts de réévaluation.
108. Compte de l'exploitant.`;

console.log(createChartOfAccountsTree(input));

关键优化点

  1. 正则匹配提取:通过/^(\d+)[.:]\s*(.*?)\.?\s*$/准确分隔ID和科目名称,自动处理:和.两种分隔符,同时清除名称末尾的.和多余空格。
  2. 全局节点索引:先将所有节点存入accounts对象,确保父节点查找时一定存在(因为输入是按层级从高到低排列)。
  3. 层级关联逻辑:通过ID长度计算父ID,将当前节点挂载到父节点的children对象中。
  4. 返回顶级节点:最终只返回ID长度为1的顶级节点,符合树形结构的根节点要求。

内容的提问来源于stack exchange,提问作者salmen ben ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:26:00