sculp-js 1.1.0 → 1.2.1

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.
Files changed (50) hide show
  1. package/README.md +6 -2
  2. package/lib/cjs/array.js +1 -178
  3. package/lib/cjs/async.js +1 -1
  4. package/lib/cjs/clipboard.js +1 -1
  5. package/lib/cjs/cookie.js +1 -1
  6. package/lib/cjs/date.js +1 -1
  7. package/lib/cjs/dom.js +1 -1
  8. package/lib/cjs/download.js +1 -1
  9. package/lib/cjs/easing.js +1 -1
  10. package/lib/cjs/file.js +1 -1
  11. package/lib/cjs/func.js +1 -1
  12. package/lib/cjs/index.js +7 -4
  13. package/lib/cjs/number.js +1 -1
  14. package/lib/cjs/object.js +1 -1
  15. package/lib/cjs/path.js +1 -1
  16. package/lib/cjs/qs.js +1 -1
  17. package/lib/cjs/random.js +1 -1
  18. package/lib/cjs/string.js +1 -1
  19. package/lib/cjs/tooltip.js +1 -1
  20. package/lib/cjs/tree.js +283 -0
  21. package/lib/cjs/type.js +1 -1
  22. package/lib/cjs/unique.js +1 -1
  23. package/lib/cjs/url.js +1 -1
  24. package/lib/cjs/watermark.js +1 -1
  25. package/lib/es/array.js +2 -176
  26. package/lib/es/async.js +1 -1
  27. package/lib/es/clipboard.js +1 -1
  28. package/lib/es/cookie.js +1 -1
  29. package/lib/es/date.js +1 -1
  30. package/lib/es/dom.js +1 -1
  31. package/lib/es/download.js +1 -1
  32. package/lib/es/easing.js +1 -1
  33. package/lib/es/file.js +1 -1
  34. package/lib/es/func.js +1 -1
  35. package/lib/es/index.js +3 -2
  36. package/lib/es/number.js +1 -1
  37. package/lib/es/object.js +1 -1
  38. package/lib/es/path.js +1 -1
  39. package/lib/es/qs.js +1 -1
  40. package/lib/es/random.js +1 -1
  41. package/lib/es/string.js +1 -1
  42. package/lib/es/tooltip.js +1 -1
  43. package/lib/es/tree.js +277 -0
  44. package/lib/es/type.js +1 -1
  45. package/lib/es/unique.js +1 -1
  46. package/lib/es/url.js +1 -1
  47. package/lib/es/watermark.js +1 -1
  48. package/lib/index.d.ts +86 -64
  49. package/lib/umd/index.js +273 -175
  50. package/package.json +7 -3
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/array.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -107,179 +107,5 @@ function arrayRemove(array, expect) {
107
107
  indexes.forEach((val, idx) => array.splice(val - idx, 1));
108
108
  return array;
109
109
  }
110
- /**
111
- * 自定义深度优先遍历函数(支持continue和break操作)
112
- * @param {ArrayLike<V>} tree 树形数据
113
- * @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
114
- * @param {string} children 定制子元素的key
115
- * @param {boolean} isReverse 是否反向遍历
116
- * @returns {*}
117
- */
118
- function forEachDeep(tree, iterator, children = 'children', isReverse = false) {
119
- let level = 0, isBreak = false;
120
- const walk = (arr, parent) => {
121
- if (isReverse) {
122
- for (let i = arr.length - 1; i >= 0; i--) {
123
- if (isBreak) {
124
- break;
125
- }
126
- const re = iterator(arr[i], i, tree, parent, level);
127
- if (re === false) {
128
- isBreak = true;
129
- break;
130
- }
131
- else if (re === true) {
132
- continue;
133
- }
134
- // @ts-ignore
135
- if (Array.isArray(arr[i][children])) {
136
- ++level;
137
- // @ts-ignore
138
- walk(arr[i][children], arr[i]);
139
- }
140
- }
141
- }
142
- else {
143
- for (let i = 0; i < arr.length; i++) {
144
- if (isBreak) {
145
- break;
146
- }
147
- const re = iterator(arr[i], i, tree, parent, level);
148
- if (re === false) {
149
- isBreak = true;
150
- break;
151
- }
152
- else if (re === true) {
153
- continue;
154
- }
155
- // @ts-ignore
156
- if (Array.isArray(arr[i][children])) {
157
- ++level;
158
- // @ts-ignore
159
- walk(arr[i][children], arr[i]);
160
- }
161
- }
162
- }
163
- };
164
- walk(tree, null);
165
- }
166
- /**
167
- * 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
168
- *
169
- * @param {ArrayLike<T>} tree - 树形数据
170
- * @param {IdLike} nodeId - 元素ID
171
- * @param {ITreeConf} config - 迭代配置项
172
- * @returns {[IdLike[], ITreeItem<V>[]]} - 由parentId...childId, parentObject-childObject组成的二维数组
173
- */
174
- function searchTreeById(tree, nodeId, config) {
175
- const { children = 'children', id = 'id' } = config || {};
176
- const toFlatArray = (tree, parentId, parent) => {
177
- return tree.reduce((t, _) => {
178
- const child = _[children];
179
- return [
180
- ...t,
181
- parentId ? { ..._, parentId, parent } : _,
182
- ...(child && child.length ? toFlatArray(child, _[id], _) : [])
183
- ];
184
- }, []);
185
- };
186
- const getIds = (flatArray) => {
187
- let child = flatArray.find(_ => _[id] === nodeId);
188
- const { parent, parentId, ...other } = child;
189
- let ids = [nodeId], nodes = [other];
190
- while (child && child.parentId) {
191
- ids = [child.parentId, ...ids];
192
- nodes = [child.parent, ...nodes];
193
- child = flatArray.find(_ => _[id] === child.parentId); // eslint-disable-line
194
- }
195
- return [ids, nodes];
196
- };
197
- return getIds(toFlatArray(tree));
198
- }
199
- /**
200
- * 使用迭代函数转换数组
201
- * @param {T} array
202
- * @param {Function} callback 迭代函数
203
- * @return {Array}
204
- */
205
- function flatMap(array, callback) {
206
- const result = [];
207
- array.forEach((value, index) => {
208
- result.push(...callback(value, index, array));
209
- });
210
- return result;
211
- }
212
- /**
213
- * 根据 idProp 与 parentIdProp 从对象数组中构建对应的树
214
- * 当 A[parentIdProp] === B[idProp] 时,对象A会被移动到对象B的children。
215
- * 当一个对象的 parentIdProp 不与其他对象的 idProp 字段相等时,该对象被作为树的顶层节点
216
- * @param {string} idProp 元素ID
217
- * @param {string} parentIdProp 父元素ID
218
- * @param {object[]} items 一维数组
219
- * @returns {WithChildren<T>[]} 树
220
- * @example
221
- * const array = [
222
- * { id: 'node-1', parent: 'root' },
223
- * { id: 'node-2', parent: 'root' },
224
- * { id: 'node-3', parent: 'node-2' },
225
- * { id: 'node-4', parent: 'node-2' },
226
- * { id: 'node-5', parent: 'node-4' },
227
- * ]
228
- * const tree = buildTree('id', 'parent', array)
229
- * expect(tree).toEqual([
230
- * { id: 'node-1', parent: 'root' },
231
- * {
232
- * id: 'node-2',
233
- * parent: 'root',
234
- * children: [
235
- * { id: 'node-3', parent: 'node-2' },
236
- * {
237
- * id: 'node-4',
238
- * parent: 'node-2',
239
- * children: [{ id: 'node-5', parent: 'node-4' }],
240
- * },
241
- * ],
242
- * },
243
- * ])
244
- */
245
- function buildTree(idProp, parentIdProp, items) {
246
- const wrapperMap = new Map();
247
- const ensure = (id) => {
248
- if (wrapperMap.has(id)) {
249
- return wrapperMap.get(id);
250
- }
251
- //@ts-ignore
252
- const wrapper = { id, parent: null, item: null, children: [] };
253
- wrapperMap.set(id, wrapper);
254
- return wrapper;
255
- };
256
- for (const item of items) {
257
- const parentWrapper = ensure(item[parentIdProp]);
258
- const itemWrapper = ensure(item[idProp]);
259
- //@ts-ignore
260
- itemWrapper.parent = parentWrapper;
261
- //@ts-ignore
262
- parentWrapper.children.push(itemWrapper);
263
- //@ts-ignore
264
- itemWrapper.item = item;
265
- }
266
- const topLevelWrappers = flatMap(Array.from(wrapperMap.values()).filter(wrapper => wrapper.parent === null), wrapper => wrapper.children);
267
- return unwrapRecursively(topLevelWrappers);
268
- function unwrapRecursively(wrapperArray) {
269
- const result = [];
270
- for (const wrapper of wrapperArray) {
271
- if (wrapper.children.length === 0) {
272
- result.push(wrapper.item);
273
- }
274
- else {
275
- result.push({
276
- ...wrapper.item,
277
- children: unwrapRecursively(wrapper.children)
278
- });
279
- }
280
- }
281
- return result;
282
- }
283
- }
284
110
 
285
- export { arrayEach, arrayEachAsync, arrayInsertBefore, arrayLike, arrayRemove, buildTree, forEachDeep, searchTreeById };
111
+ export { arrayEach, arrayEachAsync, arrayInsertBefore, arrayLike, arrayRemove };
package/lib/es/async.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/cookie.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/date.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/dom.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/easing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/file.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/func.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
- export { arrayEach, arrayEachAsync, arrayInsertBefore, arrayLike, arrayRemove, buildTree, forEachDeep, searchTreeById } from './array.js';
7
+ export { arrayEach, arrayEachAsync, arrayInsertBefore, arrayLike, arrayRemove } from './array.js';
8
8
  export { copyText } from './clipboard.js';
9
9
  export { cookieDel, cookieGet, cookieSet } from './cookie.js';
10
10
  export { calculateDate, calculateDateTime, dateParse, dateToEnd, dateToStart, formatDate, isValidDate } from './date.js';
@@ -24,3 +24,4 @@ export { STRING_POOL, randomNumber, randomString, randomUuid } from './random.js
24
24
  export { HEX_POOL, formatNumber, numberAbbr, numberToHex } from './number.js';
25
25
  export { UNIQUE_NUMBER_SAFE_LENGTH, uniqueNumber, uniqueString } from './unique.js';
26
26
  export { tooltipEvent } from './tooltip.js';
27
+ export { buildTree, forEachDeep, forEachMap, formatTree, searchTreeById } from './tree.js';
package/lib/es/number.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/object.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/path.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/qs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/random.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/string.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/tooltip.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/tree.js ADDED
@@ -0,0 +1,277 @@
1
+ /*!
2
+ * sculp-js v1.2.1
3
+ * (c) 2023-2023 chandq
4
+ * Released under the MIT License.
5
+ */
6
+
7
+ const defaultFieldOptions = { keyField: 'key', childField: 'children', pidField: 'pid' };
8
+ /**
9
+ * 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
10
+ * @param {ArrayLike<V>} tree 树形数据
11
+ * @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
12
+ * @param {string} children 定制子元素的key
13
+ * @param {boolean} isReverse 是否反向遍历
14
+ * @returns {*}
15
+ */
16
+ function forEachDeep(tree, iterator, children = 'children', isReverse = false) {
17
+ let level = 0, isBreak = false;
18
+ const walk = (arr, parent) => {
19
+ if (isReverse) {
20
+ for (let i = arr.length - 1; i >= 0; i--) {
21
+ if (isBreak) {
22
+ break;
23
+ }
24
+ const re = iterator(arr[i], i, arr, tree, parent, level);
25
+ if (re === false) {
26
+ isBreak = true;
27
+ break;
28
+ }
29
+ else if (re === true) {
30
+ continue;
31
+ }
32
+ // @ts-ignore
33
+ if (arr[i] && Array.isArray(arr[i][children])) {
34
+ ++level;
35
+ // @ts-ignore
36
+ walk(arr[i][children], arr[i]);
37
+ }
38
+ }
39
+ }
40
+ else {
41
+ for (let i = 0; i < arr.length; i++) {
42
+ if (isBreak) {
43
+ break;
44
+ }
45
+ const re = iterator(arr[i], i, arr, tree, parent, level);
46
+ if (re === false) {
47
+ isBreak = true;
48
+ break;
49
+ }
50
+ else if (re === true) {
51
+ continue;
52
+ }
53
+ // @ts-ignore
54
+ if (arr[i] && Array.isArray(arr[i][children])) {
55
+ ++level;
56
+ // @ts-ignore
57
+ walk(arr[i][children], arr[i]);
58
+ }
59
+ }
60
+ }
61
+ };
62
+ walk(tree, null);
63
+ }
64
+ /**
65
+ * 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
66
+ * @param {ArrayLike<V>} tree 树形数据
67
+ * @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
68
+ * @param {string} children 定制子元素的key
69
+ * @param {boolean} isReverse 是否反向遍历
70
+ * @returns {any[]} 新的一棵树
71
+ */
72
+ function forEachMap(tree, iterator, children = 'children', isReverse = false) {
73
+ let level = 0, isBreak = false;
74
+ const newTree = [];
75
+ const walk = (arr, parent, newTree) => {
76
+ if (isReverse) {
77
+ for (let i = arr.length - 1; i >= 0; i--) {
78
+ if (isBreak) {
79
+ break;
80
+ }
81
+ const re = iterator(arr[i], i, arr, tree, parent, level);
82
+ if (re === false) {
83
+ isBreak = true;
84
+ break;
85
+ }
86
+ else if (re === true) {
87
+ continue;
88
+ }
89
+ newTree.push(re);
90
+ // @ts-ignore
91
+ if (arr[i] && Array.isArray(arr[i][children])) {
92
+ ++level;
93
+ newTree[newTree.length - 1][children] = [];
94
+ // @ts-ignore
95
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
96
+ }
97
+ else {
98
+ // children非有效数组时,移除该属性字段
99
+ delete re[children];
100
+ }
101
+ }
102
+ }
103
+ else {
104
+ for (let i = 0; i < arr.length; i++) {
105
+ if (isBreak) {
106
+ break;
107
+ }
108
+ const re = iterator(arr[i], i, arr, tree, parent, level);
109
+ if (re === false) {
110
+ isBreak = true;
111
+ break;
112
+ }
113
+ else if (re === true) {
114
+ continue;
115
+ }
116
+ newTree.push(re);
117
+ // @ts-ignore
118
+ if (arr[i] && Array.isArray(arr[i][children])) {
119
+ ++level;
120
+ newTree[newTree.length - 1][children] = [];
121
+ // @ts-ignore
122
+ walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
123
+ }
124
+ else {
125
+ // children非有效数组时,移除该属性字段
126
+ delete re[children];
127
+ }
128
+ }
129
+ }
130
+ };
131
+ walk(tree, null, newTree);
132
+ return newTree;
133
+ }
134
+ /**
135
+ * 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
136
+ *
137
+ * @param {ArrayLike<T>} tree - 树形数据
138
+ * @param {IdLike} nodeId - 元素ID
139
+ * @param {ITreeConf} config - 迭代配置项
140
+ * @returns {[IdLike[], ITreeItem<V>[]]} - 由parentId...childId, parentObject-childObject组成的二维数组
141
+ */
142
+ function searchTreeById(tree, nodeId, config) {
143
+ const { children = 'children', id = 'id' } = config || {};
144
+ const toFlatArray = (tree, parentId, parent) => {
145
+ return tree.reduce((t, _) => {
146
+ const child = _[children];
147
+ return [
148
+ ...t,
149
+ parentId ? { ..._, parentId, parent } : _,
150
+ ...(child && child.length ? toFlatArray(child, _[id], _) : [])
151
+ ];
152
+ }, []);
153
+ };
154
+ const getIds = (flatArray) => {
155
+ let child = flatArray.find(_ => _[id] === nodeId);
156
+ const { parent, parentId, ...other } = child;
157
+ let ids = [nodeId], nodes = [other];
158
+ while (child && child.parentId) {
159
+ ids = [child.parentId, ...ids];
160
+ nodes = [child.parent, ...nodes];
161
+ child = flatArray.find(_ => _[id] === child.parentId); // eslint-disable-line
162
+ }
163
+ return [ids, nodes];
164
+ };
165
+ return getIds(toFlatArray(tree));
166
+ }
167
+ /**
168
+ * 使用迭代函数转换数组
169
+ * @param {T} array
170
+ * @param {Function} callback 迭代函数
171
+ * @returns {Array}
172
+ */
173
+ function flatMap(array, callback) {
174
+ const result = [];
175
+ array.forEach((value, index) => {
176
+ result.push(...callback(value, index, array));
177
+ });
178
+ return result;
179
+ }
180
+ /**
181
+ * 根据 idProp 与 parentIdProp 从对象数组中构建对应的树
182
+ * 当 A[parentIdProp] === B[idProp] 时,对象A会被移动到对象B的children。
183
+ * 当一个对象的 parentIdProp 不与其他对象的 idProp 字段相等时,该对象被作为树的顶层节点
184
+ * @param {string} idProp 元素ID
185
+ * @param {string} parentIdProp 父元素ID
186
+ * @param {object[]} items 一维数组
187
+ * @returns {WithChildren<T>[]} 树
188
+ * @example
189
+ * const array = [
190
+ * { id: 'node-1', parent: 'root' },
191
+ * { id: 'node-2', parent: 'root' },
192
+ * { id: 'node-3', parent: 'node-2' },
193
+ * { id: 'node-4', parent: 'node-2' },
194
+ * { id: 'node-5', parent: 'node-4' },
195
+ * ]
196
+ * const tree = buildTree('id', 'parent', array)
197
+ * expect(tree).toEqual([
198
+ * { id: 'node-1', parent: 'root' },
199
+ * {
200
+ * id: 'node-2',
201
+ * parent: 'root',
202
+ * children: [
203
+ * { id: 'node-3', parent: 'node-2' },
204
+ * {
205
+ * id: 'node-4',
206
+ * parent: 'node-2',
207
+ * children: [{ id: 'node-5', parent: 'node-4' }],
208
+ * },
209
+ * ],
210
+ * },
211
+ * ])
212
+ */
213
+ function buildTree(idProp, parentIdProp, items) {
214
+ const wrapperMap = new Map();
215
+ const ensure = (id) => {
216
+ if (wrapperMap.has(id)) {
217
+ return wrapperMap.get(id);
218
+ }
219
+ //@ts-ignore
220
+ const wrapper = { id, parent: null, item: null, children: [] };
221
+ wrapperMap.set(id, wrapper);
222
+ return wrapper;
223
+ };
224
+ for (const item of items) {
225
+ const parentWrapper = ensure(item[parentIdProp]);
226
+ const itemWrapper = ensure(item[idProp]);
227
+ //@ts-ignore
228
+ itemWrapper.parent = parentWrapper;
229
+ //@ts-ignore
230
+ parentWrapper.children.push(itemWrapper);
231
+ //@ts-ignore
232
+ itemWrapper.item = item;
233
+ }
234
+ const topLevelWrappers = flatMap(Array.from(wrapperMap.values()).filter(wrapper => wrapper.parent === null), wrapper => wrapper.children);
235
+ return unwrapRecursively(topLevelWrappers);
236
+ function unwrapRecursively(wrapperArray) {
237
+ const result = [];
238
+ for (const wrapper of wrapperArray) {
239
+ if (wrapper.children.length === 0) {
240
+ result.push(wrapper.item);
241
+ }
242
+ else {
243
+ result.push({
244
+ ...wrapper.item,
245
+ children: unwrapRecursively(wrapper.children)
246
+ });
247
+ }
248
+ }
249
+ return result;
250
+ }
251
+ }
252
+ /**
253
+ * 扁平化数组转换成树(效率高于buildTree)
254
+ * @param {any[]} list
255
+ * @param {IFieldOptions} options
256
+ * @returns {any[]}
257
+ */
258
+ function formatTree(list, options = defaultFieldOptions) {
259
+ const { keyField, childField, pidField } = options;
260
+ const treeArr = [];
261
+ const sourceMap = {};
262
+ list.forEach(item => {
263
+ sourceMap[item[keyField]] = item;
264
+ });
265
+ list.forEach(item => {
266
+ const parent = sourceMap[item[pidField]];
267
+ if (parent) {
268
+ (parent[childField] || (parent[childField] = [])).push(item);
269
+ }
270
+ else {
271
+ treeArr.push(item);
272
+ }
273
+ });
274
+ return treeArr;
275
+ }
276
+
277
+ export { buildTree, forEachDeep, forEachMap, formatTree, searchTreeById };
package/lib/es/type.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/unique.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/url.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.0.1
2
+ * sculp-js v1.2.1
3
3
  * (c) 2023-2023 chandq
4
4
  * Released under the MIT License.
5
5
  */