模式匹配以查找列表的最后一个元素

时间:2017-05-15 05:20:10

标签: scala pattern-matching

我试图使用模式匹配在scala中找到列表的最后一个元素。我尝试了以下代码

def last[A](list: List[A]):A = list match {
 case head :: Nil => head
 case head :: tail => last(tail)
 case _ => Nil
 }

最后一种情况,即案例_ => Nil因类型不匹配而抛出错误(发现Nil.type需要A)

我知道这个问题可以通过其他方法解决,但只使用模式匹配是否有办法解决这个问题?

由于列表是泛型类型,所以我不能用类型A的默认值替换Nil,它只能在运行时确定。

删除此行: case _ => Nil 显然正在发挥作用,但警告说如果Nil参数会失败。

那么,在这种情况下如何处理Nil参数呢?

3 个答案:

答案 0 :(得分:27)

您可以使用:+进行模式匹配。

def last[A](list: List[A]) = list match {
  case init :+ last => Some(last)
  case _ => None
}

答案 1 :(得分:3)

使用Option[T]返回结果,所以如果有一些元素返回Some(lastElement),否则Option.empty

示例,

  def last[A](list: List[A]): Option[A] = list match {
    case head :: Nil => Option(head)
    case head :: tail => last(tail)
    case _ => Option.empty
  }

  it("returns last element") {

    assert(last(List("apple")) == Some("apple"))
    assert(last(List("apple", "mango")) == Some("mango"))
    assert(last(List()) == Option.empty)
    assert(last(List()) == None)

  }

如何访问Option[T]

last(List("In absentia", "deadwind")) match {
  case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}") //prints Yayy there was lastValue = deadwind
  case None => println("Oops list was empty")
}

last(List()) match {
  case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}")
  case None => println("Oops list was empty") //prints Oops list was empty
}

// or using map
last(List("In absentia", "deadwind")).map(lastValue => print(s"lastValue is ${lastValue}"))

答案 2 :(得分:2)

由于您不确定您的列表是否包含任何对象,因此您应该以一般方式处理此类情况。我建议您在last方法中返回选项类型,如下所示:

def last[A](list: List[A]): Option[A] = list match {
    case head :: Nil => Some(head)
    case head :: tail => last(tail)
    case _ => None
}

然后在您的代码中,您可以使用类似monad的界面来处理结果。您可以使用map并使用提供的函数处理数据,也可以使用get方法选项,以防您完全确定列表不为空。