List 使用模式匹配查找列表中的下一个元素
我正在玩scala模式匹配,试图创建findNext函数:List 使用模式匹配查找列表中的下一个元素,list,scala,pattern-matching,List,Scala,Pattern Matching,我正在玩scala模式匹配,试图创建findNext函数: findNext(1,List(1,2,3)) == 2 findNext(2,List(1,2,3)) == 3 findNext(3,List(1,2,3)) == 1 def findNext(needle : Int, haystack : List[Int]): Int = { haystack match { case Nil => /* handle it */ case nee
findNext(1,List(1,2,3)) == 2
findNext(2,List(1,2,3)) == 3
findNext(3,List(1,2,3)) == 1
def findNext(needle : Int, haystack : List[Int]): Int = {
haystack match {
case Nil => /* handle it */
case needle::Nil => needle
case front::needle::back => back.head
case needle::back::Nil => back.head
}
}
我能让它只对一件小事起作用
这可以通过模式匹配来实现吗?我知道我可以使用列表中的方法使它工作,但这只是一个玩具程序
def findNext(needle : Int, haystack : List[Int]): Option[Int] = {
@annotation.tailrec def loop(needle : Int, haystack : List[Int], trueHead: Int): Option[Int] =
haystack match {
case Nil => None
case `needle` :: next :: _ => Some(next)
case `needle` :: Nil => Some(trueHead)
case _ :: tail => loop(needle, tail, trueHead)
}
haystack match {
case Nil | _ :: Nil => None
case _ => loop(needle, haystack, haystack.head)
}
}
有关模式匹配中的回标记,请参见
用法:
scala> findNext(1,List(1,2,3))
res0: Option[Int] = Some(2)
scala> findNext(2,List(1,2,3))
res1: Option[Int] = Some(3)
scala> findNext(3,List(1,2,3))
res2: Option[Int] = Some(1)
scala> findNext(4,List(1,2,3))
res3: Option[Int] = None
scala> findNext(1,List(1,1))
res4: Option[Int] = Some(1)
scala> findNext(1,List(1))
res5: Option[Int] = None
scala> findNext(1,List())
res6: Option[Int] = None
有关模式匹配中的回标记,请参见
用法:
scala> findNext(1,List(1,2,3))
res0: Option[Int] = Some(2)
scala> findNext(2,List(1,2,3))
res1: Option[Int] = Some(3)
scala> findNext(3,List(1,2,3))
res2: Option[Int] = Some(1)
scala> findNext(4,List(1,2,3))
res3: Option[Int] = None
scala> findNext(1,List(1,1))
res4: Option[Int] = Some(1)
scala> findNext(1,List(1))
res5: Option[Int] = None
scala> findNext(1,List())
res6: Option[Int] = None
由于可能找不到指针,因此最好在此处返回
选项[Int]
。仅使用模式匹配,您可以通过以下方法解决此问题:
@tailrec def findNext(needle: Int, haystack: List[Int]): Option[Int] = {
haystack match {
case Nil => None
case front::next::back if front == needle => Some(next)
case head::tail => findNext(needle, tail)
}
}
或者更简单:
@tailrec def findNext(needle: Int, haystack : List[Int]): Option[Int] = {
haystack match {
case Nil => None
case head::tail if head == needle => tail.headOption
case head::tail => findNext(needle, tail)
}
}
请注意,与上面的示例不同,如果在haystack中未找到匹配项,则返回None。然后,该函数的结果可以与默认答案相结合,如下所示:
val haystack = List(1,2,3,4)
findNext(4, haystack) getOrElse haystack.head
由于可能找不到指针,因此最好在此处返回
选项[Int]
。仅使用模式匹配,您可以通过以下方法解决此问题:
@tailrec def findNext(needle: Int, haystack: List[Int]): Option[Int] = {
haystack match {
case Nil => None
case front::next::back if front == needle => Some(next)
case head::tail => findNext(needle, tail)
}
}
或者更简单:
@tailrec def findNext(needle: Int, haystack : List[Int]): Option[Int] = {
haystack match {
case Nil => None
case head::tail if head == needle => tail.headOption
case head::tail => findNext(needle, tail)
}
}
请注意,与上面的示例不同,如果在haystack中未找到匹配项,则返回None。然后,该函数的结果可以与默认答案相结合,如下所示:
val haystack = List(1,2,3,4)
findNext(4, haystack) getOrElse haystack.head
如果最后一个元素是
针
,则在if
条件的帮助下,该循环回到原始haystack
的头部。findNextR
保存最后一个元素为指针时的保存值
def findNext(needle: Int, haystack: List[Int]): Option[Int] = {
@annotation.tailrec def findNextR(needle: Int, haystack: List[Int], savedHead: Int): Option[Int] = {
haystack match{
case Nil => None
case head :: tail => if (head == needle && tail.isEmpty) Some(savedHead)
else if (head == needle) Some(tail.head)
else findNextR(needle, tail, savedHead)
}
}
findNextR(needle, haystack, haystack.head)
}
scala> :load findNext.scala
Loading findNext.scala...
findNext: (needle: Int, haystack: List[Int])Option[Int]
scala> findNext(1, List(1,2,3))
res0: Option[Int] = Some(2)
scala> findNext(2, List(1,2,3))
res1: Option[Int] = Some(3)
scala> findNext(3, List(1,2,3))
res2: Option[Int] = Some(1)
如果最后一个元素是针
,则在if
条件的帮助下,该循环回到原始haystack
的头部。findNextR
保存最后一个元素为指针时的保存值
def findNext(needle: Int, haystack: List[Int]): Option[Int] = {
@annotation.tailrec def findNextR(needle: Int, haystack: List[Int], savedHead: Int): Option[Int] = {
haystack match{
case Nil => None
case head :: tail => if (head == needle && tail.isEmpty) Some(savedHead)
else if (head == needle) Some(tail.head)
else findNextR(needle, tail, savedHead)
}
}
findNextR(needle, haystack, haystack.head)
}
scala> :load findNext.scala
Loading findNext.scala...
findNext: (needle: Int, haystack: List[Int])Option[Int]
scala> findNext(1, List(1,2,3))
res0: Option[Int] = Some(2)
scala> findNext(2, List(1,2,3))
res1: Option[Int] = Some(3)
scala> findNext(3, List(1,2,3))
res2: Option[Int] = Some(1)
+1表示建议@tailrec,因为这是处理“下一步”更直接、更简单的方法。+1表示建议@tailrec,因为这是处理“下一步”更直接、更简单的方法。findNext(3,List(1,2,3))==1
这将返回选项[Int]=无
,示例显示它返回了干草堆的头部
。添加了关于此的注释。我不确定作者是否有意这样做。@alexwriteshere是的,“findNext”操作应该是循环的。不过,这帮了大忙。findNext(4,List(1))getOrElse haystack.head==1
对于findNext(3,List(1,2,3))==1
这将返回选项[Int]=None
,示例显示它返回干草堆的头部。添加了一个关于此的注释。我不确定作者是否有意这样做。@alexwriteshere是的,“findNext”操作应该是循环的。这对我们帮助很大。findNext(4,List(1))getOrElse haystack.head==1