to-tree-smart
Version:
A smart and efficient tree data structure converter that transforms flat arrays into hierarchical tree structures
1 lines • 4.66 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * 树节点的通用接口\n */\nexport interface TreeNode {\n id: number;\n parentId: number | null;\n children?: TreeNode[];\n [key: string]: any;\n}\n\n/**\n * 配置选项\n */\nexport interface ToTreeSmartOptions {\n /** ID 字段名,默认为 'id' */\n idKey?: string;\n /** 父 ID 字段名,默认为 'parentId' */\n parentIdKey?: string;\n /** 子节点字段名,默认为 'children' */\n childrenKey?: string;\n /** 是否保留空的 children 数组,默认为 false */\n keepEmptyChildren?: boolean;\n}\n\n/**\n * 将扁平数组转换为树形结构\n * 使用 Map 数据结构实现 O(n) 时间复杂度\n *\n * @param data - 要转换的扁平数组\n * @param options - 配置选项\n * @returns 树形结构的根节点数组\n *\n * @example\n * ```typescript\n * const flatData = [\n * { id: 1, name: 'Root', parentId: null },\n * { id: 2, name: 'Child 1', parentId: 1 },\n * { id: 3, name: 'Child 2', parentId: 1 },\n * { id: 4, name: 'Grandchild', parentId: 2 }\n * ];\n *\n * const tree = toTreeSmart(flatData);\n * // 结果:\n * // [\n * // {\n * // id: 1,\n * // name: 'Root',\n * // parentId: null,\n * // children: [\n * // {\n * // id: 2,\n * // name: 'Child 1',\n * // parentId: 1,\n * // children: [\n * // { id: 4, name: 'Grandchild', parentId: 2 }\n * // ]\n * // },\n * // { id: 3, name: 'Child 2', parentId: 1 }\n * // ]\n * // }\n * // ]\n * ```\n */\nexport function toTreeSmart<T extends TreeNode>(\n data: T[],\n options: ToTreeSmartOptions = {},\n): T[] {\n const {\n idKey = 'id',\n parentIdKey = 'parentId',\n childrenKey = 'children',\n keepEmptyChildren = false,\n } = options;\n\n // 使用 Map 构建节点映射,时间复杂度 O(n)\n const nodeMap = new Map<number, T>();\n\n // 第一次遍历:初始化所有节点\n data.forEach((item) => {\n (item as any)[childrenKey] = []; // 初始化children为空数组\n nodeMap.set((item as any)[idKey], item);\n });\n\n const roots: T[] = [];\n\n // 第二次遍历:构建树形结构\n data.forEach((item) => {\n const currentNode = nodeMap.get((item as any)[idKey]);\n const parentId = (item as any)[parentIdKey];\n\n if (parentId !== null && parentId !== undefined && nodeMap.has(parentId)) {\n // 有父节点,将当前节点添加到父节点的 children 中\n const parentNode = nodeMap.get(parentId);\n if (parentNode) {\n ((parentNode as any)[childrenKey] as T[]).push(currentNode as T);\n }\n } else {\n // 没有父节点,说明是根节点\n roots.push(currentNode as T);\n }\n });\n\n // 如果不保留空的 children 数组,则递归删除\n if (!keepEmptyChildren) {\n const removeEmptyChildren = (node: any) => {\n if (node[childrenKey] && node[childrenKey].length > 0) {\n node[childrenKey].forEach(removeEmptyChildren);\n } else if (node[childrenKey] && node[childrenKey].length === 0) {\n delete node[childrenKey];\n }\n };\n roots.forEach(removeEmptyChildren);\n }\n\n return roots;\n}\n\n// 默认导出\nexport default toTreeSmart;\n"],"names":[],"mappings":"AAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCG;SACa,WAAW,CACzB,IAAS,EACT,UAA8B,EAAE,EAAA;AAEhC,IAAA,MAAM,EACJ,KAAK,GAAG,IAAI,EACZ,WAAW,GAAG,UAAU,EACxB,WAAW,GAAG,UAAU,EACxB,iBAAiB,GAAG,KAAK,GAC1B,GAAG,OAAO;;AAGX,IAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAa;;AAGpC,IAAA,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACnB,QAAA,IAAY,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAE,IAAY,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;AACzC,IAAA,CAAC,CAAC;IAEF,MAAM,KAAK,GAAQ,EAAE;;AAGrB,IAAA,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;QACpB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAE,IAAY,CAAC,KAAK,CAAC,CAAC;AACrD,QAAA,MAAM,QAAQ,GAAI,IAAY,CAAC,WAAW,CAAC;AAE3C,QAAA,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;;YAExE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YACxC,IAAI,UAAU,EAAE;gBACZ,UAAkB,CAAC,WAAW,CAAS,CAAC,IAAI,CAAC,WAAgB,CAAC;YAClE;QACF;aAAO;;AAEL,YAAA,KAAK,CAAC,IAAI,CAAC,WAAgB,CAAC;QAC9B;AACF,IAAA,CAAC,CAAC;;IAGF,IAAI,CAAC,iBAAiB,EAAE;AACtB,QAAA,MAAM,mBAAmB,GAAG,CAAC,IAAS,KAAI;AACxC,YAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;gBACrD,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC;YAChD;AAAO,iBAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;AAC9D,gBAAA,OAAO,IAAI,CAAC,WAAW,CAAC;YAC1B;AACF,QAAA,CAAC;AACD,QAAA,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC;IACpC;AAEA,IAAA,OAAO,KAAK;AACd;;;;"}