【问题标题】:Filtering a list of object based on nested type根据嵌套类型过滤对象列表
【发布时间】:2012-11-15 22:03:53
【问题描述】:

假设我有一个类如下:

case class Person(
name:String,
age:Int,
dependents:List[Person]
)

假设我有以下四个人:

val p1 = Person("Tom",50,List(p2,p4))
val p2 = Person("Bob",20,List(p3))
val p3 = Person("Jimmy",25,List(p4))
val p4 = Person("Harry",11,Nil)

我的人员列表是 val pList = List(p1,p2,p3,p4)

我想过滤此集合以获取所有有 11 岁受抚养人的人。

有什么方法可以做到这一点?

算法可以总结为对于pList中每个人(p)的每个被抚养人(d),如果被抚养人(d)的年龄== 11,则收集这个人(p)。

如何在scala中表达?

【问题讨论】:

    标签: algorithm scala collections iteration


    【解决方案1】:

    您对算法的描述很好地转换为 scala 中的 for comprehension

    对于 pList 中每个人 (p) 的每个受抚养人 (d),如果年龄 依赖(d)是== 11,收集人(p)

    我们遍历pList 并在每次迭代时创建一个新变量person。如果此人的家属符合监护条件,我们从pListyield 该人。即if person.dependents.exists(dependent => dependent.age == 11)

    使用foryield

    for(person <- pList if person.dependents.exists(dependent => dependent.age == 11)) yield person
    

    这给出了两个人的列表:

    List[Person] = List(
      Person(Tom,50,List(Person(Bob,20,List(Person(Jimmy,25,List(Person(Harry,11,List()))))),     
      Person(Harry,11,List()))), Person(Jimmy,25,List(Person(Harry,11,List())))
    )
    

    【讨论】:

    • 只是一个查询,因为我还在学习 Scala:这被翻译成地图和过滤器,不是吗。
    • 是的。使用-Xprint:typer 编译显示没有糖pList.withFilter(((person) =&gt; person.dependents.exists(((dependent) =&gt; dependent.age.$eq$eq(11))))).map(((person) =&gt; person)) 的for 表达式
    【解决方案2】:

    获取人员列表,并对其使用过滤器方法,检查每个受抚养人是否包含年龄为 11 岁的人员。

    pList.filter(_.dependents.exists(_.age == 11))
    

    这显然只会检查 1 层深度,因此在您的示例中,它将返回 TomJimmy,因为它们是唯一的 Persons,其直系亲属为 11 岁:

    Person(
      Tom,
      50,
      List(Person(Bob,20,List(Person(Jimmy,25,List(Person(Harry,11,List()))))), Person(Harry,11,List()))
      )
    Person(
      Jimmy,
      25,
      List(Person(Harry,11,List()))
      )
    

    或者你可以让它更通用一点:

    def dependentAged(age: Int)(person: Person) = person.dependents.exists(_.age == age)
    val filtered = pList.filter(dependentAged(11))
    

    【讨论】:

    • 我不得不提一下,当对象图中存在(错误的)循环时,后者会失败。
    • 嗯,你能修复/提供一个例子吗?
    • @ziggystar - 很难用不可变的案例类创建循环。
    猜你喜欢
    • 2020-03-11
    • 2023-02-11
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    相关资源
    最近更新 更多