Skip to content

Commit f588056

Browse files
committed
chore: improve params naming
1 parent 1322ea0 commit f588056

File tree

2 files changed

+46
-38
lines changed

2 files changed

+46
-38
lines changed

src/tree.ts

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export function forEachDeep<V>(
9090
}
9191
if (breadthFirst) {
9292
// Process queue
93-
while (!isBreak) {
93+
while (queue.length > 0 && !isBreak) {
9494
const current = queue.shift();
9595

9696
// iterate(info);
@@ -138,7 +138,7 @@ export function forEachDeep<V>(
138138
}
139139
}
140140
if (breadthFirst) {
141-
while (!isBreak) {
141+
while (queue.length > 0 && !isBreak) {
142142
const current = queue.shift();
143143
if (!current) break;
144144
// @ts-ignore
@@ -171,70 +171,78 @@ export function forEachDeep<V>(
171171
* 可遍历任何带有 length 属性和数字键的类数组对象
172172
* @param {ArrayLike<V>} tree 树形数据
173173
* @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
174-
* @param {string} children 定制子元素的key
175-
* @param {boolean} isReverse 是否反向遍历
174+
* @param {options} options 支持定制子元素名称、反向遍历,默认{
175+
childField: 'children',
176+
reverse: false,
177+
}
176178
* @returns {any[]} 新的一棵树
177179
*/
178180
export function mapDeep<T>(
179181
tree: T[],
180182
iterator: (
181183
val: T,
182-
i: number,
184+
index: number,
183185
currentArr: T[],
184186
tree: T[],
185187
parent: T | null,
186188
level: number
187189
) => { [k: string | number]: any } | boolean,
188-
children: string = 'children',
189-
isReverse = false
190+
options: { childField?: string; reverse?: boolean; breadthFirst?: boolean } = {
191+
childField: 'children',
192+
reverse: false
193+
}
190194
): any[] {
195+
const { childField = 'children', reverse = false } = isObject(options) ? options : {};
191196
let isBreak = false;
192197
const newTree = [];
193198
const walk = (arr: T[], parent: T | null, newTree: any[], level = 0) => {
194-
if (isReverse) {
199+
if (reverse) {
195200
for (let i = arr.length - 1; i >= 0; i--) {
196201
if (isBreak) {
197202
break;
198203
}
199-
const re = iterator(arr[i], i, arr, tree, parent, level);
204+
205+
const item = arr[i];
206+
const re = iterator(item, i, arr, tree, parent, level);
200207
if (re === false) {
201208
isBreak = true;
202209
break;
203210
} else if (re === true) {
204211
continue;
205212
}
206-
newTree.push(objectOmit(re, [children as any]));
213+
newTree.push(objectOmit(re, [childField as any]));
207214
// @ts-ignore
208-
if (arr[i] && Array.isArray(arr[i][children])) {
209-
newTree[newTree.length - 1][children] = [];
215+
if (item && Array.isArray(item[childField])) {
216+
newTree[newTree.length - 1][childField] = [];
210217
// @ts-ignore
211-
walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
218+
walk(item[childField], item, newTree[newTree.length - 1][childField], level + 1);
212219
} else {
213220
// children非有效数组时,移除该属性字段
214-
delete re[children];
221+
delete re[childField];
215222
}
216223
}
217224
} else {
218225
for (let i = 0; i < arr.length; i++) {
219226
if (isBreak) {
220227
break;
221228
}
222-
const re = iterator(arr[i], i, arr, tree, parent, level);
229+
const item = arr[i];
230+
const re = iterator(item, i, arr, tree, parent, level);
223231
if (re === false) {
224232
isBreak = true;
225233
break;
226234
} else if (re === true) {
227235
continue;
228236
}
229-
newTree.push(objectOmit(re, [children as any]));
237+
newTree.push(objectOmit(re, [childField as any]));
230238
// @ts-ignore
231-
if (arr[i] && Array.isArray(arr[i][children])) {
232-
newTree[newTree.length - 1][children] = [];
239+
if (item && Array.isArray(item[childField])) {
240+
newTree[newTree.length - 1][childField] = [];
233241
// @ts-ignore
234-
walk(arr[i][children], arr[i], newTree[newTree.length - 1][children], level + 1);
242+
walk(item[childField], item, newTree[newTree.length - 1][childField], level + 1);
235243
} else {
236244
// children非有效数组时,移除该属性字段
237-
delete re[children];
245+
delete re[childField];
238246
}
239247
}
240248
}
@@ -246,39 +254,41 @@ export function mapDeep<T>(
246254
return newTree;
247255
}
248256
export type IdLike = number | string;
249-
export interface ITreeConf {
250-
id: string | number;
251-
children: string;
252-
}
257+
export type ITreeConf = Omit<IFieldOptions, 'pidField'>;
253258
/**
254259
* 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
255260
*
256261
* @param {ArrayLike<T>} tree - 树形数据
257-
* @param {IdLike} nodeId - 元素ID
258-
* @param {ITreeConf} config - 迭代配置项
259-
* @returns {[IdLike[], ITreeItem<V>[]]} - 由parentId...childId, parentObject-childObject组成的二维数组
262+
* @param {number | string} nodeId - 目标元素ID
263+
* @param {ITreeConf} options - 迭代配置项, 默认:{ children = 'children', id = 'id' }
264+
* @returns {[(number | string)[], V[]]} - 由parentId...childId, parentObject-childObject组成的二维数组
260265
*/
261-
export function searchTreeById<V>(tree: ArrayLike<V>, nodeId: IdLike, config?: ITreeConf): [IdLike[], ArrayLike<V>[]] {
262-
const { children = 'children', id = 'id' } = config || {};
266+
export function searchTreeById<V>(
267+
tree: ArrayLike<V>,
268+
nodeId: IdLike,
269+
options: ITreeConf = { childField: 'children', keyField: 'id' }
270+
): [(number | string)[], ArrayLike<V>[]] {
271+
const { childField = 'children', keyField = 'id' } = isObject(options) ? options : {};
272+
263273
const toFlatArray = (tree, parentId?: IdLike, parent?: any) => {
264274
return tree.reduce((t, _) => {
265-
const child = _[children];
275+
const child = _[childField];
266276
return [
267277
...t,
268278
parentId ? { ..._, parentId, parent } : _,
269-
...(child && child.length ? toFlatArray(child, _[id], _) : [])
279+
...(child && child.length ? toFlatArray(child, _[keyField], _) : [])
270280
];
271281
}, []);
272282
};
273283
const getIds = (flatArray): [IdLike[], ArrayLike<V>[]] => {
274-
let child = flatArray.find(_ => _[id] === nodeId);
284+
let child = flatArray.find(_ => _[keyField] === nodeId);
275285
const { parent, parentId, ...other } = child;
276286
let ids = [nodeId],
277287
nodes = [other];
278288
while (child && child.parentId) {
279289
ids = [child.parentId, ...ids];
280290
nodes = [child.parent, ...nodes];
281-
child = flatArray.find(_ => _[id] === child.parentId); // eslint-disable-line
291+
child = flatArray.find(_ => _[keyField] === child.parentId); // eslint-disable-line
282292
}
283293
return [ids, nodes];
284294
};

test/tree.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { AnyObject } from './../src/type';
21
import { cloneDeep } from '../src/cloneDeep';
32
import { formatTree, searchTreeById, forEachDeep, mapDeep, fuzzySearchTree, flatTree } from '../src/tree';
43
import './utils';
@@ -26,7 +25,7 @@ test('searchTreeById', () => {
2625

2726
const res1 = searchTreeById(tree, 3);
2827
const res2 = searchTreeById(tree, 21);
29-
const res3 = searchTreeById(tree2, 21, { id: 'key', children: 'child' });
28+
const res3 = searchTreeById(tree2, 21, { keyField: 'key', childField: 'child' });
3029
expect(res1).toStrictEqual([[3], [{ id: 3, name: 'row3' }]]);
3130
expect(res2).toStrictEqual([
3231
[2, 21],
@@ -526,7 +525,7 @@ test('mapDeep', () => {
526525
({ id, name, childNodes }) => {
527526
return { key: id, label: name, childNodes };
528527
},
529-
'childNodes'
528+
{ childField: 'childNodes' }
530529
) as any[];
531530
expect(res0).toEqual([
532531
{ key: 1, label: 'row1' },
@@ -558,8 +557,7 @@ test('mapDeep', () => {
558557
({ id, name, children }) => {
559558
return { key: id, label: name, children };
560559
},
561-
'children',
562-
true
560+
{ reverse: true }
563561
);
564562
expect(res2).toEqual([
565563
{ key: 3, label: 'row3' },

0 commit comments

Comments
 (0)