• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

[TypeScript]将一个列表转为树形列表的函数(通用型)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

今天分享一个自己实现的基于 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
)

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
TypeScript 看见未来的 JavaScript发布时间:2022-07-18
下一篇:
使用vscode写typescript(node.js环境)起手式发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap