我有一个学生列表,我想从中找到年龄为23岁的最后匹配的学生。
我知道find()
方法为我们提供了第一个匹配事件,如下所示:
case class Student(id: Int, age: Int)
val students = List(Student(1, 23), Student(2, 24), Student(3, 23))
val firstStudentWithAge23 = students.find(student => student.age == 23)
// Some(Student(1, 23))
此代码为我提供了第一个匹配的学生。但我需要最后一位匹配的学生。
目前,我使用的是reverse
方法,后跟find
:
val lastStudentWithAge23 = students.reverse.find(student => student.age == 23)
// Some(Student(3,23))
这给了我最后一个匹配的学生。
但这似乎不是一个好方法,因为必须先颠倒整个清单。如何以更好的功能方式实现这一目标?
答案 0 :(得分:5)
As of Scala 2.13,您可以使用findLast
查找满足条件的Seq
的最后一个元素:
val students = List(Student(1, 23), Student(2, 24), Student(3, 23))
students.findLast(_.age == 23) // Option[Student] = Some(Student(3, 23))
答案 1 :(得分:4)
chengpohi
&{39}和jwvh
的答案有效,但会遍历列表两次或更多次。
这是查找仅会遍历列表一次的最后一次出现的通用方法:
def findLast[A](la: List[A])(f: A => Boolean): Option[A] =
la.foldLeft(Option.empty[A]) { (acc, cur) =>
if (f(cur)) Some(cur)
else acc
}
我们只完成一次集合,并始终采用与谓词f
匹配的最后一个元素。
答案 2 :(得分:3)
我想也许你可以通过filter
和lastOption
实现这一目标,例如:
list.filter(student => student.age == 23).lastOption
答案 3 :(得分:2)
list.lift(list.lastIndexWhere(_.age == 23))
List
上的索引不是最佳选择,但它是一种选择。
答案 4 :(得分:2)
另一种方法,使用partition
,例如如下,
val (l, _) = list.partition(_.age == 23)
l.lastOption
将原始列表中出现顺序为23岁的元组的列表分成两部分,其余部分。从第一个元组开始,取最后一个项目。