Scala:写一个好用的Tree工具
一、定义IdName特质
包含Id和Name
trait Id {
val fdId: String
}
trait Name {
val name: String
}
trait IdName extends Id with Name
二、定义引用类(父类)
/**
* 关联对象
*
* @param fdId ID
* @param name 名字
*/
case class Relevance(fdId: String = "-", name: String = "-") extends IdName
三、定义Tree特质
包含parent和children,children使用的java版本的,你懂的scala的集合类转Json是比较痛苦的。
trait Tree extends IdName {
val parent: Relevance
val children: util.List[AnyRef]
}
四、创建Tree工具类
这里用伴生对象
object Tree {
/**
* 创建树
*
* @param data 数据
* @param root 根 (fdId, parent)
* @tparam T 类型
* @return
*/
def create[T <: Tree](data: Seq[T], root: (String, String) = ("root", "-1")): Seq[T] = {
for (d <- data; if d.parent.fdId == root._2 || d.fdId == root._1) yield {
recursionFn(data, d); d
}
}
/**
* 递归列表
*
* @param data 所有数据
* @param parent 父节点
*/
private def recursionFn[T <: Tree2](data: Seq[T], parent: T): Unit = {
val children = data.filter(_.parent.fdId == parent.fdId)
parent.children.addAll(children.asJava)
children.foreach(nextChild => recursionFn(data, nextChild))
}
}
五、使用
以组织架构树为例子
1. 定义一个 OrgTree case calss 集成 Tree特质
case class OrgTree(fdId: String, name: String, parent: Relevance, children: util.List[AnyRef]) extends Tree
2. 从数据库查询数据并转换为Tree
/**
* 组织架构树
*
* @return
*/
def tree: Future[Seq[OrgTree]] = {
val p = Promise[Seq[OrgTree]]()
val all = db.run(table.sortBy(_.sequence).map(d => (d.fdId, d.name, d.parent)).result)
all onComplete {
case Success(data) =>
p.success(Tree.create(data map t2TreeDTO))
case Failure(exception) =>
p.failure(exception)
}
p.future
}
/**
* 特质转TreeDTO
*
* @param t3 (fdId, name, parent)
* @return
*/
private def t2TreeDTO(t3: (String, String, String)): OrgTree = {
implicit val dbRun = (id: String) => db.run(findParentCompiled(id).result.head)
OrgTree(t3._1, t3._2, findParentByCache(t3._3), new util.ArrayList[AnyRef]())
}
findParentByCache 是根据父类ID查询父类信息的函数
六、效果
七、Tree 完整代码
import java.util
import scala.jdk.CollectionConverters.SeqHasAsJava
/**
* @author Rubin
* @version v1 2020/11/7 11:28
*/
trait Tree extends IdName {
val parent: Relevance
val children: util.List[AnyRef]
}
object Tree {
/**
* 创建树
*
* @param data 数据
* @param root 根
* @tparam T 类型
* @return
*/
def create[T <: Tree](data: Seq[T], root: (String, String) = ("root", "-1")): Seq[T] = {
for (d <- data; if d.parent.fdId == root._2 || d.fdId == root._1) yield {
recursionFn(data, d); d
}
}
/**
* 递归列表
*
* @param data 所有数据
* @param parent 父节点
*/
private def recursionFn[T <: Tree](data: Seq[T], parent: T): Unit = {
val children = data.filter(_.parent.fdId == parent.fdId)
parent.children.addAll(children.asJava)
children.foreach(nextChild => recursionFn(data, nextChild))
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!