高效优雅地从列表 class 结构中删除元素
remove elements from a List of case class structure efficiently and elegantly
我在 List
中有一个嵌套的 case
classes 结构
为简单起见,将使用以下示例 -
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]
;现在,如果我想通过为每个没有特定 zipCode
值的 Person
过滤 Address
来创建一个新的 List[Department]
;传统上我们可以做以下事情
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 学习 Lenses。到目前为止,我学到的是当你必须 "modify" 一个深度嵌套的 case
class 结构但还没有找到 "chop off" 某些部分的方法时,Lenses 很有用基于条件的嵌套结构和 return 新结构。这可能通过单片眼镜吗?另外我不确定 Lenses 是否也能帮助实现更好的 Big O 时间?
以下在性能方面基本上等同于您的实施,但可以说更清楚:
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))
这只是构建一个遍历以导航到每个人的地址列表,以便您可以根据谓词对其进行修改。我不确定是否有更好的方法来执行过滤(因为邮政编码不能用作唯一索引),但也许 Julien 会考虑一个。
我在 List
case
classes 结构
为简单起见,将使用以下示例 -
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]
;现在,如果我想通过为每个没有特定 zipCode
值的 Person
过滤 Address
来创建一个新的 List[Department]
;传统上我们可以做以下事情
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 学习 Lenses。到目前为止,我学到的是当你必须 "modify" 一个深度嵌套的 case
class 结构但还没有找到 "chop off" 某些部分的方法时,Lenses 很有用基于条件的嵌套结构和 return 新结构。这可能通过单片眼镜吗?另外我不确定 Lenses 是否也能帮助实现更好的 Big O 时间?
以下在性能方面基本上等同于您的实施,但可以说更清楚:
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))
这只是构建一个遍历以导航到每个人的地址列表,以便您可以根据谓词对其进行修改。我不确定是否有更好的方法来执行过滤(因为邮政编码不能用作唯一索引),但也许 Julien 会考虑一个。