tree-processor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 tree-processor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # tree-processor
2
+
3
+ 树结构数据处理工具,目前已支持 mapTree、filterTree、findTree、pushTree、unshiftTree、popTree、shiftTree、someTree、everyTree、atTree、indexOfTree、atIndexOfTree、nodeDepthMap 和 dedupTree。每个方法的最后一个参数可以自定义 children 和 id 的属性名。
4
+
5
+ ## 安装教程
6
+
7
+ ```bash
8
+ yarn add tree-processor
9
+ # 或
10
+ npm i tree-processor
11
+ ```
12
+
13
+ ## 使用说明
14
+
15
+ ### 引入
16
+
17
+ #### 默认导入(推荐用于需要多个方法的场景)
18
+
19
+ ```javascript
20
+ // ES Module
21
+ import t from 'tree-processor'
22
+
23
+ // CommonJS
24
+ const t = require('tree-processor')
25
+ ```
26
+
27
+ #### 按需导入(推荐用于只需要少量方法的场景,支持 tree-shaking)
28
+
29
+ ```javascript
30
+ // ES Module - 按需导入单个方法
31
+ import { mapTree, filterTree, findTree } from 'tree-processor'
32
+
33
+ // ES Module - 按需导入类型
34
+ import type { TreeNode, TreeData, FieldNames } from 'tree-processor'
35
+
36
+ // CommonJS - 按需导入
37
+ const { mapTree, filterTree } = require('tree-processor')
38
+ ```
39
+
40
+ **按需导入的优势:**
41
+ - ✅ 支持 tree-shaking,只打包使用的代码,减小打包体积
42
+ - ✅ 更好的代码提示和类型检查
43
+ - ✅ 更清晰的依赖关系
44
+
45
+ ### 示例树结构数据
46
+
47
+ 以下示例数据将用于后续所有方法的演示:
48
+
49
+ ```javascript
50
+ const treeData = [
51
+ {
52
+ id: 1,
53
+ name: 'node1',
54
+ children: [
55
+ {
56
+ id: 2,
57
+ name: 'node2',
58
+ children: [
59
+ { id: 4, name: 'node4' },
60
+ { id: 5, name: 'node5' },
61
+ ],
62
+ },
63
+ {
64
+ id: 3,
65
+ name: 'node3',
66
+ children: [{ id: 6, name: 'node6' }],
67
+ },
68
+ ],
69
+ },
70
+ ];
71
+ ```
72
+
73
+ ### mapTree(遍历树结构数据的方法)
74
+
75
+ 遍历树结构数据,对每个节点执行回调函数。
76
+
77
+ ```javascript
78
+ t.mapTree(treeData, (item) => {
79
+ console.log(item)
80
+ })
81
+ ```
82
+
83
+ ### filterTree(树结构数据的filter方法)
84
+
85
+ 过滤树结构数据,返回满足条件的节点。
86
+
87
+ ```javascript
88
+ const values = ['node1', 'node2', 'node3'];
89
+ const result = t.filterTree(treeData, (item) => {
90
+ return values.includes(item.name)
91
+ })
92
+
93
+ console.log(result)
94
+ ```
95
+
96
+ ### findTree(树结构数据的find方法)
97
+
98
+ 查找树结构数据中满足条件的第一个节点。
99
+
100
+ ```javascript
101
+ const result = t.findTree(treeData, (item) => {
102
+ return item.hasOwnProperty('children')
103
+ })
104
+
105
+ console.log(result)
106
+ ```
107
+
108
+ ### pushTree(在指定节点下添加子节点到末尾)
109
+
110
+ targetParentId 为目标节点的 id,newNode 为往该节点添加的数据。
111
+
112
+ ```javascript
113
+ t.pushTree(treeData, targetParentId, newNode);
114
+
115
+ console.log(treeData)
116
+ ```
117
+
118
+ ### unshiftTree(在指定节点下添加子节点到开头)
119
+
120
+ targetParentId 为目标节点的 id,newNode 为往该节点添加的数据。
121
+
122
+ ```javascript
123
+ t.unshiftTree(treeData, targetParentId, newNode);
124
+
125
+ console.log(treeData)
126
+ ```
127
+
128
+ ### popTree(删除指定节点下的最后一个子节点)
129
+
130
+ rootId 为目标节点的 id,此方法可删除 rootId 下的最后一个子节点。
131
+
132
+ ```javascript
133
+ t.popTree(treeData, rootId);
134
+
135
+ console.log(treeData)
136
+ ```
137
+
138
+ ### shiftTree(删除指定节点下的第一个子节点)
139
+
140
+ rootId 为目标节点的 id,此方法可删除 rootId 下的第一个子节点。
141
+
142
+ ```javascript
143
+ t.shiftTree(treeData, rootId);
144
+
145
+ console.log(treeData)
146
+ ```
147
+
148
+ ### someTree(树结构数据的some方法)
149
+
150
+ 检查树结构数据中是否存在满足条件的节点。
151
+
152
+ ```javascript
153
+ const result = t.someTree(treeData, item => item.name === 'jack')
154
+
155
+ console.log(result)
156
+ ```
157
+
158
+ ### everyTree(树结构数据的every方法)
159
+
160
+ 检查树结构数据中是否所有节点都满足条件。
161
+
162
+ ```javascript
163
+ const result = t.everyTree(treeData, item => item.age >= 18)
164
+
165
+ console.log(result)
166
+ ```
167
+
168
+ ### atTree(根据父节点ID和子节点索引获取节点)
169
+
170
+ parentId 为指定父节点的 id,nodeIndex 为子节点的索引,可传负数,和数组的 at 方法一样。
171
+
172
+ ```javascript
173
+ const result = t.atTree(treeData, parentId, nodeIndex)
174
+
175
+ console.log(result)
176
+ ```
177
+
178
+ ### indexOfTree(返回从根节点到目标节点的索引路径)
179
+
180
+ 返回一个数组,值为从根节点开始到 targetId 所在节点的索引,返回值可以传入 atIndexOfTree 的第二个参数进行取值。
181
+
182
+ ```javascript
183
+ const result = t.indexOfTree(treeData, targetId)
184
+
185
+ console.log(result)
186
+ ```
187
+
188
+ ### atIndexOfTree(根据索引路径获取节点)
189
+
190
+ 传入节点数据的下标数组,返回节点数据。
191
+
192
+ ```javascript
193
+ const result = t.atIndexOfTree(treeData, [0, 1, 0])
194
+
195
+ console.log(result)
196
+ ```
197
+
198
+ ### nodeDepthMap(返回节点ID到深度的映射)
199
+
200
+ 返回一个字典,键代表节点的 id,值代表该节点在数据的第几层。
201
+
202
+ ```javascript
203
+ const result = t.nodeDepthMap(treeData)
204
+
205
+ console.log(result)
206
+ ```
207
+
208
+ ### dedupTree(树结构对象数组去重方法)
209
+
210
+ 树结构对象数组去重方法,第一个参数为需要去重的数据,第二个参数为以哪个键去重。
211
+
212
+ ```javascript
213
+ const result = t.dedupTree(treeData, 'id')
214
+
215
+ console.log(result)
216
+ ```
217
+
218
+ ## 自定义字段名
219
+
220
+ 所有方法都支持自定义 children 和 id 的属性名,通过最后一个参数传入配置对象:
221
+
222
+ ```javascript
223
+ const fieldNames = { children: 'subNodes', id: 'nodeId' };
224
+ const result = t.findTree(treeData, (item) => item.nodeId === 2, fieldNames);
225
+ ```
226
+
227
+ ## 开发
228
+
229
+ ```bash
230
+ # 安装依赖
231
+ npm install
232
+
233
+ # 运行测试
234
+ npm test
235
+
236
+ # 构建项目
237
+ npm run build
238
+ ```
239
+
240
+ ## 技术栈
241
+
242
+ - **Rollup** - 模块打包工具
243
+ - **Vitest** - 单元测试框架
244
+ - **Terser** - JavaScript 压缩工具
245
+ - **TypeScript** - 类型支持
246
+
247
+ ## License
248
+
249
+ MIT
@@ -0,0 +1,150 @@
1
+ /**
2
+ * 树结构数据处理的字段名配置
3
+ */
4
+ export interface FieldNames {
5
+ children: string;
6
+ id: string;
7
+ }
8
+ /**
9
+ * 树节点类型
10
+ */
11
+ export type TreeNode = Record<string, any>;
12
+ /**
13
+ * 树结构数据(数组形式)
14
+ */
15
+ export type TreeData = TreeNode[];
16
+ /**
17
+ * 遍历树结构数据,对每个节点执行回调函数
18
+ * @param tree 树结构数据
19
+ * @param callback 回调函数,接收节点作为参数
20
+ * @param fieldNames 自定义字段名配置
21
+ * @returns 返回映射后的扁平数组
22
+ */
23
+ export declare function mapTree(tree: TreeData, callback: (node: TreeNode) => any, fieldNames?: FieldNames): any[];
24
+ /**
25
+ * 过滤树结构数据,返回满足条件的节点
26
+ * @param tree 树结构数据
27
+ * @param filterFn 过滤函数
28
+ * @param fieldNames 自定义字段名配置
29
+ * @returns 返回满足条件的节点数组
30
+ */
31
+ export declare function filterTree(tree: TreeData, filterFn: (node: TreeNode, index: number) => boolean, fieldNames?: FieldNames): TreeData;
32
+ /**
33
+ * 查找树结构数据中满足条件的第一个节点
34
+ * @param tree 树结构数据
35
+ * @param conditionFn 条件函数
36
+ * @param fieldNames 自定义字段名配置
37
+ * @returns 返回找到的节点,未找到返回 null
38
+ */
39
+ export declare function findTree(tree: TreeData, conditionFn: (node: TreeNode) => boolean, fieldNames?: FieldNames): TreeNode | null;
40
+ /**
41
+ * 在指定父节点下添加子节点(添加到末尾)
42
+ * @param tree 树结构数据
43
+ * @param targetParentId 目标父节点ID
44
+ * @param newNode 新节点
45
+ * @param fieldNames 自定义字段名配置
46
+ * @returns 是否成功添加
47
+ */
48
+ export declare function pushTree(tree: TreeData, targetParentId: any, newNode: TreeNode, fieldNames?: FieldNames): boolean;
49
+ /**
50
+ * 在指定父节点下添加子节点(添加到开头)
51
+ * @param tree 树结构数据
52
+ * @param targetParentId 目标父节点ID
53
+ * @param newNode 新节点
54
+ * @param fieldNames 自定义字段名配置
55
+ * @returns 是否成功添加
56
+ */
57
+ export declare function unshiftTree(tree: TreeData, targetParentId: any, newNode: TreeNode, fieldNames?: FieldNames): boolean;
58
+ /**
59
+ * 删除指定节点下的最后一个子节点
60
+ * @param tree 树结构数据
61
+ * @param rootId 目标节点ID
62
+ * @param fieldNames 自定义字段名配置
63
+ * @returns 是否成功删除
64
+ */
65
+ export declare function popTree(tree: TreeData, rootId: any, fieldNames?: FieldNames): boolean;
66
+ /**
67
+ * 删除指定节点下的第一个子节点
68
+ * @param tree 树结构数据
69
+ * @param rootId 目标节点ID
70
+ * @param fieldNames 自定义字段名配置
71
+ * @returns 是否成功删除
72
+ */
73
+ export declare function shiftTree(tree: TreeData, rootId: any, fieldNames?: FieldNames): boolean;
74
+ /**
75
+ * 检查树结构数据中是否存在满足条件的节点
76
+ * @param tree 树结构数据
77
+ * @param filterFn 过滤函数
78
+ * @param fieldNames 自定义字段名配置
79
+ * @returns 如果存在满足条件的节点返回 true,否则返回 false
80
+ */
81
+ export declare function someTree(tree: TreeData, filterFn: (node: TreeNode) => boolean, fieldNames?: FieldNames): boolean;
82
+ /**
83
+ * 检查树结构数据中是否所有节点都满足条件
84
+ * @param tree 树结构数据
85
+ * @param filterFn 过滤函数
86
+ * @param fieldNames 自定义字段名配置
87
+ * @returns 如果所有节点都满足条件返回 true,否则返回 false
88
+ */
89
+ export declare function everyTree(tree: TreeData, filterFn: (node: TreeNode) => boolean, fieldNames?: FieldNames): boolean;
90
+ /**
91
+ * 根据父节点ID和子节点索引获取节点(支持负数索引)
92
+ * @param tree 树结构数据
93
+ * @param parentId 父节点ID
94
+ * @param nodeIndex 子节点索引(支持负数)
95
+ * @param fieldNames 自定义字段名配置
96
+ * @returns 返回找到的节点,未找到返回 null
97
+ */
98
+ export declare function atTree(tree: TreeData, parentId: any, nodeIndex: number, fieldNames?: FieldNames): TreeNode | null;
99
+ /**
100
+ * 返回从根节点到目标节点的索引路径
101
+ * @param tree 树结构数据
102
+ * @param targetId 目标节点ID
103
+ * @param fieldNames 自定义字段名配置
104
+ * @returns 返回索引路径数组,未找到返回 null
105
+ */
106
+ export declare function indexOfTree(tree: TreeData, targetId: any, fieldNames?: FieldNames): number[] | null;
107
+ /**
108
+ * 根据索引路径获取节点
109
+ * @param tree 树结构数据
110
+ * @param path 索引路径数组
111
+ * @param fieldNames 自定义字段名配置
112
+ * @returns 返回找到的节点,未找到返回 null
113
+ */
114
+ export declare function atIndexOfTree(tree: TreeData, path: number[], fieldNames?: FieldNames): TreeNode | null;
115
+ /**
116
+ * 返回节点ID到深度的映射字典
117
+ * @param tree 树结构数据
118
+ * @param fieldNames 自定义字段名配置
119
+ * @returns 返回节点ID到深度的映射对象
120
+ */
121
+ export declare function nodeDepthMap(tree: TreeData, fieldNames?: FieldNames): Record<string, number>;
122
+ /**
123
+ * 树结构数据去重
124
+ * @param tree 树结构数据
125
+ * @param key 用于去重的键名
126
+ * @param fieldNames 自定义字段名配置
127
+ * @returns 返回去重后的树结构数据
128
+ */
129
+ export declare function dedupTree(tree: TreeData, key: string, fieldNames?: FieldNames): TreeData;
130
+ /**
131
+ * 默认导出对象,包含所有方法
132
+ */
133
+ declare const treeProcessor: {
134
+ mapTree: typeof mapTree;
135
+ filterTree: typeof filterTree;
136
+ findTree: typeof findTree;
137
+ pushTree: typeof pushTree;
138
+ unshiftTree: typeof unshiftTree;
139
+ popTree: typeof popTree;
140
+ shiftTree: typeof shiftTree;
141
+ someTree: typeof someTree;
142
+ everyTree: typeof everyTree;
143
+ atTree: typeof atTree;
144
+ indexOfTree: typeof indexOfTree;
145
+ atIndexOfTree: typeof atIndexOfTree;
146
+ nodeDepthMap: typeof nodeDepthMap;
147
+ dedupTree: typeof dedupTree;
148
+ };
149
+ export default treeProcessor;
150
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}