树形类 - ikTree
树形数据处理的一些方法
导入方式
import { ikTree } from 'iking-utils'
interface TreeHelperConfig {
id: string;
children: string;
pid: string;
sort: string; // 排序字段名
needSort: boolean; // 是否需要排序
}
findNode
在树结构中找到满足给定条件的节点。
找到的节点,如果没有节点满足条件则返回null
findNode<T = any>(
tree: any,
func: Fn,
config: Partial<TreeHelperConfig> = {},
): T | null
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
tree | any | 要搜索的树结构 |
func | Fn | 节点要满足的条件函数 |
config | Partial<TreeHelperConfig> | 树遍历的可选配置 |
示例
<script setup>
import { ikTree } from 'iking-utils'
//定义一个树形结构
const tree = [
{
id: 1,
name: 'Node 1',
children: [
{
id: 2,
name: 'Node 2',
children: [
{
id: 3,
name: 'Node 3',
children: []
}
]
},
{
id: 4,
name: 'Node 4',
children: []
}
]
},
{
id: 5,
name: 'Node 5',
children: []
}
];
//定义一个函数来搜索指定的节点
function findNodeById(node) {
return node.id === 3;
}
//调用findNode函数查找id为3的节点
const result = ikTree.findNode(tree, findNodeById);
console.log(result); // Output: { id: 3, name: 'Node 3', children: [] }
</script>
findNodeAll
这个函数查找树中与给定函数匹配的所有节点。 它接受一个树对象、一个匹配节点的函数和一个可选的配置对象。 配置对象可以为子节点指定属性名。 该函数返回树中找到的所有匹配节点的数组。
findNodeAll<T = any>(
tree: any,
func: Fn,
config: Partial<TreeHelperConfig> = {},
): T | null
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
tree | any | 要搜索的树结构 |
func | Fn | 节点要满足的条件函数 |
config | Partial<TreeHelperConfig> | 树遍历的可选配置 |
示例
<script setup>
import { ikTree } from 'iking-utils'
//定义一个树形结构
const tree = [
{
id: 1,
name: 'Node 1',
children: [
{
id: 2,
name: 'Node 2',
children: [
{
id: 3,
name: 'Node 3',
children: []
}
]
},
{
id: 4,
name: 'Node 4',
children: []
}
]
},
{
id: 5,
name: 'Node 5',
children: []
}
];
//定义一个函数来搜索具有特定名称的节点
function findNodesByName(node) {
return node.name.includes('Node');
}
//调用findNodeAll函数查找名称包含'Node'的所有节点
const results = ikTree.findNodeAll(tree, findNodesByName);
console.log(results);
// Output: [
// { id: 1, name: 'Node 1', children: [...] },
// { id: 2, name: 'Node 2', children: [...] },
// { id: 3, name: 'Node 3', children: [] },
// { id: 4, name: 'Node 4', children: [] },
// { id: 5, name: 'Node 5', children: [] }
// ]
</script>
findPath
函数用于在树数据结构中查找与给定条件匹配的路径。
findPath<T = any>(
tree: any,
func: Fn,
config: Partial<TreeHelperConfig> = {},
): T | T[] | null
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
tree | any | 表示需要查找路径的树状数据结构。它可以是任何类型的树。 |
func | Fn | 这个参数是一个函数,它从树中获取一个节点作为输入,并返回一个布尔值,指示该节点是否符合所需的条件。 |
config | Partial<TreeHelperConfig> | 该参数是一个可选对象,允许自定义函数的行为。它包括诸如children之类的属性,它指定每个节点中子数组的属性名称。 |
示例
<script setup>
import { ikTree } from 'iking-utils'
const tree = [
{
id: 1,
name: 'Node 1',
children: [
{
id: 2,
name: 'Node 2',
children: [
{
id: 3,
name: 'Node 3',
},
{
id: 4,
name: 'Node 4',
},
],
},
{
id: 5,
name: 'Node 5',
},
],
},
{
id: 6,
name: 'Node 6',
},
];
// Define your condition function
function findNodeById(node) {
return node.id === 4;
}
// 调用findPath函数
const path = ikTree.findPath(tree, findNodeById);
console.log(path); // Output: [{ id: 1, name: 'Node 1', children: [{ id: 2, name: 'Node 2', children: [...] },{ id: 5, name: 'Node 5', children: [...] }] }, { id: 2, name: 'Node 2', children: [...] }, { id: 4, name: 'Node 4' }]
</script>
findPathAll
这个函数“findPathAll”接受一个树和一个函数,并返回树中满足给定函数的所有路径的数组。该函数还接受一个配置对象,该对象可以指定用于树中的子节点的键。
findPathAll(tree: any, func: Fn, config: Partial<TreeHelperConfig> = {})
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
tree | any | 表示需要查找路径的树状数据结构。它可以是任何类型的树。 |
func | Fn | 这个参数是一个函数,它从树中获取一个节点作为输入,并返回一个布尔值,指示该节点是否符合所需的条件。 |
config | Partial<TreeHelperConfig> | 该参数是一个可选对象,允许自定义函数的行为。它包括诸如children之类的属性,它指定每个节点中子数组的属性名称。 |
示例
<script setup>
import { ikTree } from 'iking-utils'
const tree = [
{
id: 1,
name: 'Node 1',
children: [
{
id: 2,
name: 'Node 2',
children: [
{
id: 3,
name: 'Node 3',
children: []
}
]
},
{
id: 4,
name: 'Node 4',
children: []
}
]
},
{
id: 5,
name: 'Node 5',
children: []
}
];
// 定义一个函数来搜索具有特定名称的节点
function findNodesByName(node) {
return node.name.includes('Node');
}
// 调用findPathAll函数查找到名称包含“Node”的所有节点的路径
const results = ikTree.findPathAll(tree, findNodesByName);
console.log(results);
// Output: [
// [ { id: 1, name: 'Node 1', children: [...] } ],
// [ { id: 1, name: 'Node 1', children: [...] }, { id: 2, name: 'Node 2', children: [...] } ],
// [ { id: 1, name: 'Node 1', children: [...] }, { id: 2, name: 'Node 2', children: [...] }, { id: 3, name: 'Node 3', children: [] } ],
// [ { id: 1, name: 'Node 1', children: [...] }, { id: 4, name: 'Node 4', children: [] } ],
// [ { id: 5, name: 'Node 5', children: [] } ]
// ]
</script>
filter
根据给定的过滤函数过滤元素树。
filter<T = any>(
tree: T[],
func: (n: T) => boolean,
config: Partial<TreeHelperConfig> = {},
): T[]
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
tree | any | 要过滤的元素树。 |
func | Fn | 应用于每个元素的过滤函数。 |
config | Partial<TreeHelperConfig> | 可选的配置对象,用于自定义树助手的行为。 |
示例
<script setup>
import { ikTree } from 'iking-utils'
const tree = [
{
id: 1,
name: 'Node 1',
children: [
{
id: 2,
name: 'Node 2',
children: [
{
id: 3,
name: 's3',
children: []
}
]
},
{
id: 4,
name: 'Node 4',
children: []
}
]
},
{
id: 5,
name: 'Node 5',
children: []
}
];
// 定义条件函数
function filterNodesWithName(node) {
return node.name.includes('Node');
}
// 调用findPathAll函数查找到名称包含“Node”的所有节点的路径
const filteredNodes = ikTree.filter(tree, filterNodesWithName);
console.log(filteredNodes);
// Output: [
// { id: 1, name: 'Node 1', children: [
// { id: 2, name: 'Node 2', children: [
// { id: 4, name: 'Node 4' , children: undefined}
// ]},
// { id: 5, name: 'Node 5', children: undefined }
// ]},
// { id: 6, name: 'Node 6', children: undefined}
// ]
</script>
forEach
用于遍历树状数据结构并在每个节点上执行操作
filter<T = any>(
tree: T[],
func: (n: T) => boolean,
config: Partial<TreeHelperConfig> = {},
): T[]
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
tree | any | 要过滤的元素树。 |
func | Fn | 应用于每个元素的过滤函数。 |
config | Partial<TreeHelperConfig> | 可选的配置对象,用于自定义树助手的行为。 |
示例
<script setup>
import { ikTree } from 'iking-utils'
const tree = [
{
id: 1,
name: '节点 1',
children: [
{
id: 2,
name: '节点 2',
children: [
{
id: 3,
name: 'Node 3',
},
{
id: 4,
name: 'Node 4',
},
],
},
{
id: 5,
name: '节点 5',
},
],
},
{
id: 6,
name: '节点 6',
},
];
// 定义条件函数
function filterNodesWithName(node: any) {
return node.name.includes('节点')
}
// 调用 filter 函数
const filteredNodes = ikTree.filter(tree, filterNodesWithName);
console.log(filteredNodes);
// Output: [
// { id: 1, name: '节点 1', children: [
// { id: 2, name: '节点 2', children: []},
// { id: 5, name: '节点 5', children: undefined }
// ]},
// { id: 6, name: '节点 6', children: undefined}
// ]
</script>
treeMap
提取指定结构的树 通过对树状数据结构中的每一项应用转换函数来生成一个新的数组。
包含转换项的新数组
treeMap<T = any>(treeData: T[], opt: { children?: string; conversion: Fn }): T[]
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
treeData | T[] | 要过滤的元素树。 |
opt | { children?: string; conversion: Fn } | 一个选项对象 |
opt.children | string | 每个项的子数组的属性名。默认为“children” |
opt.conversion | function | 要应用于每个项目的转换函数。 |
示例
<script setup>
import { ikTree } from 'iking-utils'
const treeData = [
{
id: 1,
name: 'Parent 1',
children: [
{
id: 2,
name: 'Child 1.1',
children: [
{
id: 3,
name: 'Grandchild 1.1.1',
children: []
},
{
id: 4,
name: 'Grandchild 1.1.2',
children: []
}
]
},
{
id: 5,
name: 'Child 1.2',
children: []
}
]
},
{
id: 6,
name: 'Parent 2',
children: [
{
id: 7,
name: 'Child 2.1',
children: []
}
]
}
];
// 定义转换函数
function convertData(data) {
return {
id: data.id,
label: data.name
};
}
// 调用treeMap
const mappedTree = ikTree.treeMap(treeData, { children: 'children', conversion: convertData });
console.log(mappedTree);
// Output: [
// {
// id: 1,
// label: 'Parent 1',
// children: [
// {
// id: 2,
// label: 'Child 1.1',
// children: [
// {
// id: 3,
// label: 'Grandchild 1.1.1',
// children: []
// },
// {
// id: 4,
// label: 'Grandchild 1.1.2',
// children: []
// }
// ]
// },
// {
// id: 5,
// label: 'Child 1.2',
// children: []
// }
// ]
// },
// {
// id: 6,
// label: 'Parent 2',
// children: [
// {
// id: 7,
// label: 'Child 2.1',
// children: []
// }
// ]
// }
// ]
</script>
treeMapEach
提取指定结构的树 提取指定结构的树
总的来说,该函数递归地映射树结构中的每个节点,将转换函数应用于每个节点,并保留父节点和子节点之间的层次关系
treeMapEach(
data: any,
{ children = 'children', conversion }: { children?: string; conversion: Fn },
)
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
treeData | T[] | 要过滤的元素树。 |
opt | { children?: string; conversion: Fn } | 一个可选的对象参数 |
opt.children | string | 每个项的子数组的属性名。默认为“children” |
opt.conversion | function | 要应用于每个项目的转换函数。 |
示例
<script setup>
import { ikTree } from 'iking-utils'
const treeData = [
{
id: 1,
name: 'Parent 1',
children: [
{
id: 2,
name: 'Child 1.1',
children: [
{
id: 3,
name: 'Grandchild 1.1.1',
children: []
},
{
id: 4,
name: 'Grandchild 1.1.2',
children: []
}
]
},
{
id: 5,
name: 'Child 1.2',
children: []
}
]
},
{
id: 6,
name: 'Parent 2',
children: [
{
id: 7,
name: 'Child 2.1',
children: []
}
]
}
];
// 定义返回函数
function convertData(data, opt) {
return data.map((item: any) => ikTree.treeMapEach(item, opt));
}
// 定义转换函数
function convertData(data) {
return {
id: data.id,
label: data.name
};
}
// 调用treeMap
const mappedTree = convertData(treeData, { children: 'children', conversion: convertData });
console.log(mappedTree);
// Output: [
// {
// id: 1,
// label: 'Parent 1',
// children: [
// {
// id: 2,
// label: 'Child 1.1',
// children: [
// {
// id: 3,
// label: 'Grandchild 1.1.1',
// children: []
// },
// {
// id: 4,
// label: 'Grandchild 1.1.2',
// children: []
// }
// ]
// },
// {
// id: 5,
// label: 'Child 1.2',
// children: []
// }
// ]
// },
// {
// id: 6,
// label: 'Parent 2',
// children: [
// {
// id: 7,
// label: 'Child 2.1',
// children: []
// }
// ]
// }
// ]
</script>
listToTree
将节点的平面列表转换为树结构
返回转换成树结构的节点列表。
listToTree
<T extends {
__nodekey?: number,
config?: TreeHelperConfig,
[key:string]: any }>
(list: T[], config: Partial<TreeHelperConfig> = {}): T[]
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
list | T[] | 节点的平面列表 |
config | Partial<TreeHelperConfig> | 一个可选的对象参数 |
示例
<script setup>
import { ikTree } from 'iking-utils'
const treeList = [
{
id: 1,
label: 'Parent 1'
parentId: null
},
{
id: 2,
label: 'Child 1.1',
parentId: 1
},
{
id: 213,
label: 'Grandchild 1.1.1',
parentId: 2
},
{
id: 214,
label: 'Grandchild 1.1.2',
parentId: 2
},
{
id: 65,
label: 'Child 1.2',
parentId: 6
},
{
id: 67,
label: 'Child 2.1',
parentId: 6
},
{
id: 6,
label: 'Parent 2',
parentId: null
}
];
// 定义树形结构的配置
const config = {
pid: 'parentId',
id: 'id',
}
// 调用listToTree
const treeData = ikTree.listToTree(treeList, config);
console.log(treeData);
// Output:
// [{
// id: 1,
// label: "Parent 1",
// children: [{
// id: 2,
// label: "Child 1.1",
// parentId: 1,
// children: [{
// id: 213,
// label: "Grandchild 1.1.1",
// parentId: 2
// }, {
// id: 214,
// label: "Grandchild 1.1.2",
// parentId: 2
// }]
// }]
// }, {
// id: 6,
// label: "Parent 2",
// children: [{
// id: 65,
// label: "Child 1.2",
// parentId: 6
// }, {
// id: 67,
// label: "Child 2.1",
// parentId: 6
// }]
// }]
</script>
<script setup>
import { ikTree } from 'iking-utils'
const treeList = [
{
id: 1,
label: 'Parent 1'
parentId: null
},
{
id: 2,
label: 'Child 1.1',
parentId: 1
},
{
id: 213,
label: 'Grandchild 1.1.1',
parentId: 2
},
{
id: 214,
label: 'Grandchild 1.1.2',
parentId: 2
},
{
id: 65,
label: 'Child 1.2',
parentId: 6
},
{
id: 67,
label: 'Child 2.1',
parentId: 6
},
{
id: 6,
label: 'Parent 2',
parentId: null
}
];
// 定义树形结构的配置
const config = {
pid: 'parentId',
id: 'id',
sort: 'id',
needSort: true
}
// 调用listToTree
const treeData = ikTree.listToTree(treeList, config);
console.log(treeData);
// Output:
// [{
// "id": 1,
// "label": "Parent 1",
// "children": [{
// "id": 2,
// "label": "Child 1.1",
// "parentId": 1,
// "children": [{
// "id": 213,
// "label": "Grandchild 1.1.1",
// "parentId": 2,
// "__nodekey": 111
// }, {
// "id": 214,
// "label": "Grandchild 1.1.2",
// "parentId": 2,
// "__nodekey": 112
// }],
// "__nodekey": 11
// }],
// "__nodekey": 1
// }, {
// "id": 6,
// "label": "Parent 2",
// "children": [{
// "id": 65,
// "label": "Child 1.2",
// "parentId": 6,
// "__nodekey": 21
// }, {
// "id": 67,
// "label": "Child 2.1",
// "parentId": 6,
// "__nodekey": 22
// }],
// "__nodekey": 2
// }]
</script>
setListNodeKey
将节点的平面列表转换为树结构
返回转换成树结构的节点列表。
setListNodeKey<T extends {
__nodekey?: number,
children?: T[],
[key: string]: any
}>(result: T[] | T, ind: string | number = '', conf: TreeHelperConfig)
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
list | T[] | 节点的平面列表 |
config | Partial<TreeHelperConfig> | 一个可选的对象参数 |
示例
<script setup>
import { ikTree } from 'iking-utils'
// 定义树形结构的配置
const config = {
sort: 'id' // Sorting property
};
// 定义节点的初始平面列表
const nodeList = [
{ id: 1, name: 'Node 1', children: [
{ id: 2, name: 'Node 1.1' },
{ id: 3, name: 'Node 1.2', children: [
{ id: 4, name: 'Node 1.2.1' },
{ id: 5, name: 'Node 1.2.2' }
]}
]},
{ id: 6, name: 'Node 2' }
];
// 调用setListNodeKey函数来设置节点密钥
ikTree.setListNodeKey(nodeList, '', config);
// 输出带有指定键的修改后的nodeList
console.log(nodeList);
// Output:
// [
// { id: 1, name: 'Node 1', __nodekey: 1, children: [
// { id: 2, name: 'Node 1.1', __nodekey: 11 },
// { id: 3, name: 'Node 1.2', __nodekey: 12, children: [
// { id: 4, name: 'Node 1.2.1', __nodekey: 121 },
// { id: 5, name: 'Node 1.2.2', __nodekey: 122 }
// ]}
// ]},
// { id: 6, name: 'Node 2', __nodekey: 2 }
// ]
</script>
treeToList
将树结构转换为平面列表。
返回的转换后的平面列表。
treeToList<T = any>
(tree: any, config: Partial<TreeHelperConfig> = {}): T
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
tree | any | 要转换的树结构。 |
config | Partial<TreeHelperConfig> | 配置对象 |
示例
<script setup>
import { ikTree } from 'iking-utils'
// 定义树形结构
const tree = [
{
id: 1,
name: 'Parent 1',
children: [
{
id: 2,
name: 'Child 1.1',
},
{
id: 3,
name: 'Child 1.2',
children: [
{
id: 4,
name: 'Grandchild 1.2.1',
},
{
id: 5,
name: 'Grandchild 1.2.2',
},
],
},
],
},
{
id: 6,
name: 'Parent 2',
},
];
// 调用treeToList函数将树转换为平面列表
const flatList = ikTree.treeToList(tree);
// 输出转换后的平面列表
console.log(flatList);
// Output:
// [
// { id: 1, name: 'Parent 1' },
// { id: 2, name: 'Child 1.1' },
// { id: 3, name: 'Child 1.2' },
// { id: 4, name: 'Grandchild 1.2.1' },
// { id: 5, name: 'Grandchild 1.2.2' },
// { id: 6, name: 'Parent 2' }
// ]
</script>
arrayToMapTree
接受一个节点数组,并将其转换为一个映射树结构。
数组中的每个节点由一个唯一的id表示。该函数创建一个映射其中键是节点id,值是节点本身。函数遍历数组中的每个节点并检查它是否有父节点。
如果是,则使用parentId从映射中检索父节点。如果父母节点存在,当前节点被添加到父节点的子数组。
最后,函数返回映射树结构。
<script>
export interface Node {
id: number;
name: string;
parentId?: number | null;
children?: Node[];
}
export const arrayToMapTree = (nodes: Node[]): Map<number, Node> => {
const map = new Map<number, Node>();
nodes.forEach(node => map.set(node.id, node));
nodes.forEach(node => {
if (node.parentId !== undefined && node.parentId !== null) {
const parent = map.get(node.parentId);
if (parent) {
parent.children = parent.children || [];
parent.children.push(node);
}
}
});
return map;
}
</script>
参数说明
参数值 | 类型 | 参数值说明 |
---|---|---|
nodes | Node[] | 一个要转换成地图树结构的节点数组 |
<script setup>
import { ikTree } from 'iking-utils'
// 定义Node接口
interface Node {
id: number;
parentId?: number | null;
children?: Node[];
// 其他属性字段...
}
// 定义节点数组
const nodes: Node[] = [
{ id: 1, parentId: null },
{ id: 2, parentId: 1 },
{ id: 3, parentId: 1 },
{ id: 4, parentId: 2 },
{ id: 5, parentId: 2 },
{ id: 6, parentId: 3 },
];
// 调用arrayToMapTree函数将数组转换为映射树结构
const mapTree = ikTree.arrayToMapTree(nodes);
// 输出映射树结构
console.log(mapTree);
// outPut
// Map(6) {
// 1 => { id: 1, parentId: null, children: [ [Object], [Object] ] },
// 2 => { id: 2, parentId: 1, children: [ [Object], [Object] ] },
// 3 => { id: 3, parentId: 1, children: [ [Object] ] },
// 4 => { id: 4, parentId: 2 },
// 5 => { id: 5, parentId: 2 },
// 6 => { id: 6, parentId: 3 }
// }
</script>
treeTraverse
递归遍历树,并在每次遍历时执行callback函数
<script lang="ts" setup>
type TTraverse = {
<T>(tree: T): void;
<T>(tree: T, callback?: Function): void;
<T>(tree: T, key?: string | Function, callback?: Function): void;
}
interface TreeNode<T> {
[key: string]: T | TreeNode<T>[];
}
const treeTraverse =
(<T>(tree: TreeNode<T>, key: string | Function = 'children', callback?: Function) => {
const _key: string = paramType.isString(key) ? key : 'children'
const _callback = paramType.isFunction(key) ? key : (callback ?? null)
_callback && _callback(tree);
if (tree[_key]) {
const _tree = paramType.isArray(tree[_key]) ? tree[_key] : [tree[_key]];
(_tree as TreeNode<T>[]).forEach(child => {
treeTraverse(child, callback);
});
}
}) as TTraverse
</script>
参数说明
参数值 | 类型 | 默认值 | 参数值说明 |
---|---|---|---|
tree | TreeNode<T> | - | 一个要转换成地图树结构的节点数组 |
key | String | Function | 'children' | 一个要转换成地图树结构的节点数组 |
callback | Function | - | (可选参数)回调函数 |
<script setup>
import { ikTree } from 'iking-utils'
interface Person {
name: string
children?: Person[]
}
const tree: Person = {
name: 'Alice',
children: [
{
name: 'Bob',
children: [
{
name: 'Charlie'
},
{
name: 'Dave'
}
]
},
{
name: 'Eve'
}
]
}
// 定义要在每个节点上执行的回调函数
function printName(person: Person) {
console.log(person.name)
//outPut: Alice
//outPut: Bob
//outPut: Charlie
//outPut: Dave
//outPut: Eve
}
// 用树和回调函数调用treeTraverse函数
ikTree.treeTraverse(tree, 'children', printName)
</script>