zoukankan      html  css  js  c++  java
  • [TypeScript] 将一个列表转为树形列表的函数(通用型)

    今天分享一个自己实现的基于 TypeScript 的将列表转为树形列表的通用函数。

      /**
       * 将一个列表转化为树形列表, 列表数据需要本身支持转化成数型
       * @param list 列表数据
       * @param equalLevalItem 判断两个列表项是否同级且不相等的回调函数
       * @param listFirstIsRoot 使用列表中的第1项作为树的root节点
       * @param isRootItem 判断列表项是否为root节点的回调函数,listFirstIsRoot = false 时有效
       * @param childrenField 列表项中,存放 children 列表的字段名称
       * @param childrenMust 子列表字段是否必须存在,为 true 时,如果没有子列表,会将其设置为 []
       * @param item 当前列表项, 调用者传 undefined
       * @returns
       */
      // eslint-disable-next-line max-params
      static toTreeList<T>(
        list?: T[],
        equalLevalItem?: (a: T | undefined, item: T) => boolean,
        listFirstIsRoot: boolean = true,
        isRootItem?: (e: T, index: number) => boolean,
        childrenField: string = "children",
        childrenMust: boolean = false,
        item?: T,
      ): T[] {
        const children: T[] = []
        if (! list || list.length === 0) {
          return children
        }
        const handleChildren = (e: T) => {
          let srcData = e[childrenField];
          if (childrenMust && ! srcData) {
            srcData = []
            e[childrenField] = srcData
          }
          const data: T[] | undefined = srcData ? srcData as T[] : []
          data.push(...this.toTreeList(list, equalLevalItem, listFirstIsRoot, undefined, childrenField, childrenMust, e))
          if (! srcData && data.length > 0) {
            e[childrenField] = data;
          } else if (data.length === 0 && ! childrenMust) {
            e[childrenField] = undefined
          }
        }
        let v = item
        if (v === undefined) {
          if (listFirstIsRoot) {
            v = list[0]
            if (v[childrenField] === undefined) {
              v[childrenField].children = []
            }
            handleChildren(v)
            children.push(v)
          } else {
            // 找出 root 项
            list.forEach((e, index) => {
              if (isRootItem?.(e, index)) {
                handleChildren(e)
                children.push(e)
              }
            })
          }
          return children
        }
        list.filter((e) => {
          if (equalLevalItem?.(item, e)) { return e } // 排除掉当前 item
        }).forEach((e) => {
          handleChildren(e)
          children.push(e)
        })
        return children
      }
    

    使用示例:

    Utils.toTreeList(
          list,
          (src, item) => src?.id === item.pid && src.id !== item.id,
          false,
          (item, idx) => item.pid === 0
    )
    
  • 相关阅读:
    RAND函数和SRAND函数
    称丢手帕问题
    用GDB调试程序(七)
    用GDB调试程序(六)
    用GDB调试程序(三)
    用GDB调试程序(五)
    用GDB调试程序(二)
    用GDB调试程序(一)
    SOAP 简单对象访问协议
    关于angularJS绑定数据时自动转义html标签
  • 原文地址:https://www.cnblogs.com/yangyxd/p/15557470.html
Copyright © 2011-2022 走看看