记住前面提到的不可变列表,对于
case class Person (val name: String = "",
val age:Int = 0,
val email: String = "")
(请注意,您可以为每个字段设置构造默认值)和
val list: List[Person] = List(Person("",0,"")) // compilation ok
我们也可以使用List 连接运算符++ 构造第二个List[Person],如下所示,
val list2 = list ++ List(Person(age=1))
list2: List(Person(,0,), Person(,1,))
要通过给定标准检索Person,例如在本例中,通过age,请考虑collect,如下所示,
val list3 = list2.collect { case p@Person(_, age, _) if age == 1 => p }
List[Person] = List(Person(,1,))
这里我们提取感兴趣的字段age,并检查一个条件(是否等于1),因此我们选择list2中的那些符合条件的条目;为了提供此类条目,我们在每个 Person 实例上使用绑定 p;也许更规范(并且不必要地重复)的方法是
val list3 = list2.collect {
case Person(name, age, email) if age == 1 => Person(name, age, email) }
类似的方法依赖于filter,如下所示,
list2.filter(p => p.age == 1)
还有一个 for 理解,像这样
for ( p@Person(n, a, e) <- list2 if a == 1 ) yield p
在条目列表上定义选择的更详细的方法包括定义将谓词作为参数并针对每个条目对其进行评估的方法;此外,这可以封装在一个隐式类中以便于使用;因此考虑这个例子,
implicit class PersonsOps( val persons: List[Person] ) extends AnyVal {
def select(pred: Person => Boolean) = persons.filter(pred)
}
所以我们可以在byAge的调用中定义一个匿名函数,即(x: Person) => x.age == 1;因此
list2.select( (x: Person) => x.age == 1 )
或等效
list2.select( _.age == 1 )
请注意,在此说明性示例中,select 和 filter 是等效的或可互换的,但 select 可以根据其他要求进行丰富/扩展。