繁体   English   中英

在 Scala 列表中查找倒数第二个元素

[英]Finding the Penultimate Element in Scala List

我是 Scala 的新手,我正在学习集合上的模式匹配,以编写一个简单的逻辑来查找最后一个元素。 这是我的第一次尝试:

@scala.concurrent.tailrec
def penultimate[A](elems: List[A]) = elems match {
  case Nil => None 
  case first :: second :: Nil => Some(first)
  case head :: tail => penultimate(tail)
} 

这够好吗? 我读了关于尾递归的文章,我把我的方法变成了尾递归的方法!

但是,对于以下情况以及我期望 Some(1) 的情况,它失败了:

penultimate[Int](List(1)) // This should give me Some(1)

有什么更好的我可以做的吗? 我可以使用 Scala 集合库中的反向方法并将其设为单行,但我不想使用它。

有没有更好的方法?

如果您修复了这两个简单的编译错误,您的代码似乎可以正常工作。 编写此方法的另一种方法是:

def penultimate[A](elems: List[A]) = elems match {
  case _ :+ elem :+ _ => Some(elem)
  case elem +: Nil => Some(elem) // strange extra requirement
  case _ => None
} 

:+Seq解构为 (1) 除最后一个元素之外的所有元素的列表,以及 (2) 最后一个元素。 ::或更一般的+:但倒退。 我可以写case init :+ elem :+ last ,但我不想给我不打算使用的模式部分命名。

Penultimate 首先的要求是列表中至少应该有 2 个元素。 所以在上面的“penultimateInt”应该抛出异常。

def penultimate[A](elems: List[A]) = {
  val result = getSecondLast(elems)
  if(result.isDefined) result.get else throw new Exception("list doesn't have 
    enough elementss")
}

@tailrec
private def getSecondLast[A](list: List[A], secondLast: Option[A] = None): 
  Option[A] = {
  list match {
    case secondLast :: _ :: Nil => Some(secondLast)
    case _ :: tail => getSecondLast(tail, secondLast)
    case _ => None
  }
}

以上是递归方法。 使用可用方法的其他方法是:

  1. 列表.init.last
  2. list.takeRight(n).head

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM