@okutils/array-to-tree
v0.0.6
Published
A TypeScript utility to convert a flat array into a hierarchical tree via parent-child relationships.
Readme
@okutils/array-to-tree
一个 TypeScript 工具库,用于将扁平的数组结构通过父子关系转换为层级树结构。
这个项目基于 alferov/array-to-tree,并针对原始代码做了现代化改造、功能增强和一些错误修复。
[!IMPORTANT]
目前还没有发布 1.0 版,可能会存在 bug 或不兼容的变更。
特性
- 现代化:使用现代 TypeScript 和 ES 编写,提供更好的类型支持。
- 函数式编程:采用函数式编程范式,不修改原始数据,避免副作用。
- 可配置:允许自定义字段名和其他行为,适应不同的数据结构。
安装
# 使用 pnpm
pnpm add @okutils/array-to-tree
# 使用 yarn
yarn add @okutils/array-to-tree
# 使用 npm
npm install @okutils/array-to-tree
# 使用 Bun
bun add @okutils/array-to-tree使用方法
基本用法
import { arrayToTree } from "@okutils/array-to-tree";
const data = [
{ id: 1, name: "A", parentId: null },
{ id: 2, name: "B", parentId: 1 },
{ id: 3, name: "C", parentId: 1 },
{ id: 4, name: "D", parentId: 2 },
{ id: 5, name: "E", parentId: null },
];
const tree = arrayToTree(data);
console.log(tree);输出结果
[
{
"id": 1,
"name": "A",
"parentId": null,
"children": [
{
"id": 2,
"name": "B",
"parentId": 1,
"children": [
{
"id": 4,
"name": "D",
"parentId": 2
}
]
},
{
"id": 3,
"name": "C",
"parentId": 1
}
]
},
{
"id": 5,
"name": "E",
"parentId": null
}
]API
arrayToTree(data, options?)
data:Record<string, any>[]- 包含数据的扁平数组。options:ArrayToTreeOptions(可选) - 配置选项对象。
配置选项
您可以传入一个 options 对象来自定义字段名和其他行为。
// src/types/options.ts
export interface ArrayToTreeOptions {
childrenId?: string;
customId?: string;
parentId?: string;
allowSelfAsParent?: boolean;
}| 选项 | 类型 | 默认值 | 描述 |
| ------------------- | --------- | ------------ | ------------------------------------------------- |
| customId | string | 'id' | 指定节点唯一标识的字段名。 |
| parentId | string | 'parentId' | 指定关联父节点的字段名。 |
| childrenId | string | 'children' | 指定生成的树中用于存放子节点数组的字段名。 |
| allowSelfAsParent | boolean | false | 是否允许一个节点的 parentId 等于它自身的 id。 |
示例:使用自定义字段
import { arrayToTree } from "@okutils/array-to-tree";
const data = [
{ key: "node-1", parent: null, title: "Node 1" },
{ key: "node-2", parent: "node-1", title: "Node 2" },
];
const tree = arrayToTree(data, {
customId: "key",
parentId: "parent",
childrenId: "nodes",
});输出结果:
[
{
"key": "node-1",
"parent": null,
"title": "Node 1",
"nodes": [
{
"key": "node-2",
"parent": "node-1",
"title": "Node 2"
}
]
}
]错误类
ArrayToTreeError
用于表示在将数组转换为树结构时发生的错误。
export class ArrayToTreeError extends Error {
constructor(message: string) {
super(message);
this.name = "ArrayToTreeError";
}
}使用场景
ArrayToTreeError 会在以下情况下被抛出:
- 输入类型错误: 当传入的
data参数不是数组时
arrayToTree("not array"); // 抛出 ArrayToTreeError: Expected an array but got an invalid argument.- 重复的节点 ID: 当数组中存在相同
id的节点时
const data = [
{ id: 1, name: "A", parentId: null },
{ id: 1, name: "A-duplicate", parentId: null }, // 重复的 id
];
arrayToTree(data); // 抛出 ArrayToTreeError: Duplicate node id "1" detected.- 自引用错误: 当节点的
parentId等于自身id,且allowSelfAsParent选项为false时
const data = [
{ id: 1, name: "A", parentId: 1 }, // 自引用
];
arrayToTree(data, { allowSelfAsParent: false });
// 抛出 ArrayToTreeError: Node "1" cannot be its own parent (self reference found).- 循环引用检测: 当节点之间形成循环依赖时
const data = [
{ id: 1, name: "A", parentId: 3 },
{ id: 2, name: "B", parentId: 1 },
{ id: 3, name: "C", parentId: 2 }, // 形成循环: 1 -> 3 -> 2 -> 1
];
arrayToTree(data); // 抛出 ArrayToTreeError: Cycle detected in parent chain: 1 -> 3 -> 2 -> 1错误处理
建议使用 try-catch 捕获并处理这些错误:
import { arrayToTree, ArrayToTreeError } from "@okutils/array-to-tree";
try {
const tree = arrayToTree(data);
console.log(tree);
} catch (error) {
if (error instanceof ArrayToTreeError) {
console.error("转换失败:", error.message);
// 处理特定的转换错误
} else {
console.error("未知错误:", error);
}
}许可证
MIT © Luke Na
