首页 文章

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

提问于
浏览
5

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

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

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

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

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

删除这一行: case _ => Nil 显然正在工作,但警告说在Nil参数的情况下会失败 .

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

3 回答

  • 26

    使用 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)
    
      }
    

    How to access the 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

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

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

    由于您不确定您的列表是否包含任何对象,因此您应该以一般方式处理此类情况 . 我建议在 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 方法,以确保列表不为空 .

相关问题