如何在Scala列表中找到元素的最后一个出现位置?

时间:2017-12-03 14:57:22

标签: scala

我有一个学生列表,我想从中找到年龄为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))

这给了我最后一个匹配的学生。

但这似乎不是一个好方法,因为必须先颠倒整个清单。如何以更好的功能方式实现这一目标?

5 个答案:

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

我想也许你可以通过filterlastOption实现这一目标,例如:

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岁的元组的列表分成两部分,其余部分。从第一个元组开始,取最后一个项目。