我在case
List
类结构
为简单起见,将使用以下作为示例 -
case class Address(street: String, city: String, state: String, zipCode: Int)
case class Person(firstName: String, lastName: String, addresses: List[Address])
case class Department(people: List[Person])
说有List[Department]
;现在,如果我要为每个没有特定List[Department]
值的Address
过滤Person
来创建新的zipCode
;传统上我们可以做以下
def filterPersonsByAddress(dlist: List[Department]): List[Department] = {
dlist.map { d =>
val people = d.people.map { p =>
p.copy(addresses = p.addresses.filterNot(_.zipCode == 38978))}
d.copy(people=people)
}
}
这种方法不具备性能,因为它取决于嵌套级别,它可以是Big O(n ^ 2)或Big O(n ^ 3);
我正试图通过Monocle学习镜片。到目前为止,我所学到的是当你必须“修改”一个深层嵌套的case
类结构但尚未找到一种方法根据条件“切断”嵌套结构的某些部分时,镜头是有用的。返回一个新结构。这可能是通过Monocle吗?此外,我不确定Lenses是否能够帮助实现更好的Big O时间?
答案 0 :(得分:3)
以下内容基本上等同于您在性能方面的实现,但它可以说得更清楚:
import monocle.Traversal, monocle.macros.GenLens
import monocle.function.all._, monocle.std.list._
val deptAddresses: Traversal[Department, List[Address]] =
GenLens[Department](_.people)
.composeTraversal(each)
.composeLens(GenLens[Person](_.addresses))
val filterAddresses: Department => Department =
deptAddresses.modify(_.filterNot(_.zipCode == 38978))
这只是构建一个遍历来导航到每个人的地址列表,以便您可以根据谓词对其进行修改。我不确定是否有更好的方法来执行过滤(因为邮政编码不能作为唯一索引),但也许朱利安将权衡一个。