我有这样的结构:
case class Parent(id : Option[Long], name : String)
case class Child(id : Option[Long], parentId : Long, name : String)
val parents : List[Parent] = List(
Parent(Some(1),"John"),
Parent(Some(2),"Jake"),
Parent(Some(3),"Tamara"))
val children : List[Child] =
List(Child(id = Some(1), parentId = 1, name = "John I"),
Child(id = Some(2), parentId = 1, name = "John II"),
Child(id = Some(3), parentId = 1, name = "John III"),
Child(id = Some(4), parentId = 2, name = "Jake I"),
Child(id = Some(5), parentId = 2, name = "Jake II"),
Child(id = Some(5), parentId = 3, name = "Tamara I")
)
我如何编写一个导致这种情况的函数?
List(
(Parent(Some(1),"John"), List(Child(id = Some(1), parentId = 1, name = "John I"),Child(id = Some(2), parentId = 1, name = "John II"),Child(id = Some(3), parentId = 1, name = "John III"))),
(Parent(Some(2),"Jake"), List(Child(id = Some(4), parentId = 2, name = "Jake I"),Child(id = Some(5), parentId = 2, name = "Jake II"))),
(Parent(Some(3),"Tamara")), List(Child(id = Some(5), parentId = 3, name = "Tamara I"))),
)
我已经有这个了:
def groupParentChildren(parents : List[Parent], children : List[Child]) : List[(Parent, List[Child])] = {
children
.groupBy(_.parentId)
.map{case(parentId, children) => (parents.find(p => p.id.get == parentId), children)}
.toList
.flatMap{case(parentOpt, childrens) => parentOpt.map(parent => (parent, childrens))}
}
这似乎可以解决问题,但是在Scala中有没有更优雅的方法来实现结果?
答案 0 :(得分:2)
最优雅的可能是:
parents.map {
case p@Parent(Some(pid), _) => (p, children.filter(_.parentId == pid))
case p => (p, Nil)
}
但这确实对children
进行了许多不必要的扫描。效率更高一点:
val childrenByParentId = children.groupBy(_.parentId)
parents.map {
case p@Parent(Some(pid), _) => (p, childrenByParentId.getOrElse(pid, Nil))
case p => (p, Nil)
}