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

如何将扁平账户余额数组转换为层级化账户树?

实现扁平账户余额到层级账户树的转换

核心思路

把每个AccountBalance的codes数组看作一条层级路径,从根节点开始,沿着路径逐个查找或创建节点,同时累加每个节点的amountOut值,最终构建出完整的树结构。

步骤拆解

  • 初始化根节点存储:用Map存储顶级节点,键为codeType-code的组合,避免重复创建,同时实现快速查找。
  • 遍历处理每一条余额数据:对每个AccountBalance,沿着codes的层级依次推进:
    1. 从当前层级的父节点集合开始(初始为根节点Map)
    2. 检查当前codeType+code是否已存在对应节点:不存在则创建新节点并添加到父节点的subAccounts;存在则直接复用
    3. 将当前余额的amountOut累加到该节点的amountOut字段
    4. 切换到下一层级,把当前节点作为父节点继续处理
  • 提取最终树结构:将根节点Map的所有值转换为数组,就是最终的AccountTree。

TypeScript 实现代码

先补全基础类型定义(可根据实际场景调整):

// 账户层级代码结构
interface AccountCode {
  codeType: string;
  code: string;
}

// 扁平账户余额条目
interface AccountBalance {
  codes: AccountCode[];
  amountOut: number;
}

// 层级化账户树节点
interface AccountTreeNode {
  codeType: string;
  code: string;
  amountOut: number;
  subAccounts: AccountTreeNode[];
}

type AccountTree = AccountTreeNode[];

转换函数实现:

function convertToAccountTree(balances: AccountBalance[]): AccountTree {
  const rootNodes = new Map<string, AccountTreeNode>();

  for (const balance of balances) {
    let currentParentMap = rootNodes;
    let currentParent: AccountTreeNode | null = null;

    for (const code of balance.codes) {
      const nodeKey = `${code.codeType}-${code.code}`;
      let node = currentParentMap.get(nodeKey);

      if (!node) {
        node = {
          codeType: code.codeType,
          code: code.code,
          amountOut: 0,
          subAccounts: []
        };
        currentParentMap.set(nodeKey, node);
        // 非根节点要添加到父节点的子列表中
        currentParent?.subAccounts.push(node);
      }

      // 累加当前余额的出账金额
      node.amountOut += balance.amountOut;

      // 切换到下一层级的父节点映射
      const childMap = new Map<string, AccountTreeNode>();
      node.subAccounts.forEach(child => {
        childMap.set(`${child.codeType}-${child.code}`, child);
      });
      currentParentMap = childMap;
      currentParent = node;
    }
  }

  return Array.from(rootNodes.values());
}

输入输出验证示例

假设输入扁平数据:

const inputBalances: AccountBalance[] = [
  { codes: [{ codeType: "LEVEL1", code: "A" }, { codeType: "LEVEL2", code: "A1" }], amountOut: 100 },
  { codes: [{ codeType: "LEVEL1", code: "A" }, { codeType: "LEVEL2", code: "A2" }], amountOut: 200 },
  { codes: [{ codeType: "LEVEL1", code: "B" }, { codeType: "LEVEL2", code: "B1" }], amountOut: 150 },
  { codes: [{ codeType: "LEVEL1", code: "A" }, { codeType: "LEVEL2", code: "A1" }, { codeType: "LEVEL3", code: "A1-1" }], amountOut: 50 }
];

调用转换函数后,输出的层级树结构:

[
  {
    codeType: "LEVEL1",
    code: "A",
    amountOut: 350, // 100+200+50
    subAccounts: [
      {
        codeType: "LEVEL2",
        code: "A1",
        amountOut: 150, // 100+50
        subAccounts: [{ codeType: "LEVEL3", code: "A1-1", amountOut: 50, subAccounts: [] }]
      },
      { codeType: "LEVEL2", code: "A2", amountOut: 200, subAccounts: [] }
    ]
  },
  {
    codeType: "LEVEL1",
    code: "B",
    amountOut: 150,
    subAccounts: [{ codeType: "LEVEL2", code: "B1", amountOut: 150, subAccounts: [] }]
  }
]

关键细节说明

  • 用Map存储节点是为了O(1)时间复杂度的查找,避免同层级重复创建节点
  • 每个节点的amountOut会累加所有路径经过该节点的余额数据,符合层级汇总的需求
  • 每一层级都会切换到当前节点的子节点映射,确保层级嵌套关系正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:22:44