根据嵌套类型过滤对象列表

时间:2012-11-28 05:40:59

标签: algorithm scala collections iteration

假设我有一节课如下:

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中表达它?

2 个答案:

答案 0 :(得分:9)

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

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

这只会明显检查1层深度,因此在您的示例中,它会返回TomJimmy,因为它们是唯一具有11年直接相关性的Persons老:

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))

答案 1 :(得分:4)

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

  

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

我们遍历pList并在每次迭代时创建一个新变量person。如果此人的家属符合警卫标准,我们yield来自pList的人。即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())))
)