数组工具
大约 4 分钟
这是一个数组相关的工具类模块,提供了一些对数组的高级操作。
arrayToNested
该函数用于将一个扁平的对象数组转换为嵌套结构(树形结构),常用于菜单、分类、权限节点等需要层级结构的场景。
支持以下特性:
- 自定义 ID 与父 ID 的字段名(默认为
id和parentId) - 自定义子节点字段名(默认为
children) - 重命名字段名
- 复制字段值到新字段
- 自定义节点映射处理函数
重要
- 原始数据不会被修改,函数内部使用了深拷贝。
- 如果
parentId不存在或找不到对应的父节点,则该节点被视为顶层节点。 - 若
renameKeys与copyKeys同时操作同一字段,建议先copy再rename。 - 使用泛型
<R>可以指定输出节点类型,提高类型安全性。
参数说明
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| nodes | T[] | - | 要转换的原始对象数组,每个对象必须包含唯一标识字段(如 id)和父节点标识字段(如 parentId)。 |
| options | ToNestedOptions<T, R> | {} | 配置项 |
ToNestedOptions<T, R> 配置项对象,包含以下可选字段:
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| idKey | string | 'id' | 节点的唯一标识字段名 |
| pIdKey | string | 'parentId' | 父节点标识字段名 |
| childrenKey | string | 'children' | 子节点集合字段名 |
| renameKeys | [string, string][] | false | 重命名字段,如 [['oldKey', 'newKey']] |
| copyKeys | [string, string][] | false | 复制字段值到新字段,如 [['sourceKey', 'targetKey']] |
| mapper | (node: T) => R | undefined | 自定义节点映射函数,用于进一步处理每个节点 |
返回值
- 类型:
R[] - 说明:返回转换后的嵌套结构数组,顶层节点直接位于数组中,其子节点通过
childrenKey字段嵌套。
基本用法
const data = [
{ id: 1, parentId: null, name: '一级节点' },
{ id: 2, parentId: 1, name: '子节点' },
];
const nested = arrayToNested(data);
console.log(nested);
// 输出:
// [
// {
// id: 1,
// parentId: null,
// name: '一级节点',
// children: [
// { id: 2, parentId: 1, name: '子节点' }
// ]
// }
// ]自定义字段名
const data = [
{ key: '1', parentKey: null, label: '一级节点' },
{ key: '2', parentKey: '1', label: '子节点' },
];
const nested = arrayToNested(data, {
idKey: 'key',
pIdKey: 'parentKey',
childrenKey: 'childrenList',
});
console.log(nested);
// 输出:
// [
// {
// key: '1',
// parentKey: null,
// label: '一级节点',
// childrenList: [
// { key: '2', parentKey: '1', label: '子节点' }
// ]
// }
// ]重命名字段 + 复制字段
const data = [
{ id: 1, parentId: null, name: '一级节点' },
{ id: 2, parentId: 1, name: '子节点' },
];
const nested = arrayToNested(data, {
renameKeys: [['name', 'title']],
copyKeys: [['id', 'value']],
});
console.log(nested);
// 输出:
// [
// {
// id: 1,
// parentId: null,
// title: '一级节点',
// value: 1,
// children: [
// {
// id: 2,
// parentId: 1,
// title: '子节点',
// value: 2
// }
// ]
// }
// ]自定义映射函数
const data = [
{ id: 1, parentId: null, name: '一级节点' },
{ id: 2, parentId: 1, name: '子节点' },
];
const nested = arrayToNested(data, {
mapper: node => ({
key: node.id,
title: node.name,
isLeaf: !node.children,
}),
});
console.log(nested);
// 输出:
// [
// {
// key: 1,
// title: '一级节点',
// isLeaf: false,
// children: [
// {
// key: 2,
// title: '子节点',
// isLeaf: true
// }
// ]
// }
// ]arrayToElTreeDataStructure
该函数专门用于将扁平的对象数组转换为符合 Element Plus Tree 组件要求的数据结构。它基于 arrayToNested 函数实现,自动将指定的标签字段重命名为 label,并确保每个节点都有 children 属性。
支持以下特性:
- 自动将指定字段重命名为
label(Element Plus Tree 组件要求) - 保留
arrayToNested的所有功能(自定义 ID 字段、父 ID 字段等) - 保证每个节点都包含
children数组(空节点也会初始化为空数组)
重要
- 原始数据不会被修改,函数内部使用了深拷贝。
- 如果
labelKey未指定,则不会进行字段重命名。 - 其他配置项与
arrayToNested相同。
参数说明
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| nodes | T[] | - | 要转换的原始对象数组 |
| options | ToElTreeDataStructure<T, R> | {} | 配置项,除了 labelKey 外,其他选项与 ToNestedOptions 相同 |
ToElTreeDataStructure<T, R> 配置项对象,包含以下可选字段:
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| idKey | string | 'id' | 节点的唯一标识字段名 |
| pIdKey | string | 'parentId' | 父节点标识字段名 |
| labelKey | string | label | 指定哪个字段应该被重命名为 label |
返回值
- 类型:
R[] - 说明:返回转换后符合 Element Plus Tree 组件要求的嵌套结构数组。
基本用法
const data = [
{ id: 1, parentId: null, name: '一级节点' },
{ id: 2, parentId: 1, name: '子节点' },
];
const treeData = arrayToElTreeDataStructure(data, {
labelKey: 'name',
});
console.log(treeData);
// 输出:
// [
// {
// id: 1,
// parentId: null,
// label: '一级节点',
// children: [
// {
// id: 2,
// parentId: 1,
// label: '子节点',
// children: []
// }
// ]
// }
// ]