@@ -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 */
178180export 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}
248256export 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 } ;
0 commit comments