在 Scala 中用模式匹配替换 ._1 和 .head
Replacing ._1 and .head with pattern matching in Scala
def checkPeq[A,B](list1: List[(A, List[B])])( P: (A,B) => Boolean): List[Boolean] = {
def helper[A,B](list2: List[(A, List[B])], list3: List[B], acc1: Boolean, acc2: List[Boolean])(leq:(A,B) => Boolean): List[Boolean] = {
list2 match {
case h1::t1 => {
list3 match {
case Nil if t1!=Nil => helper(t1, t1.head._2, true, acc1::acc2)(leq)
case Nil => (acc1::acc2).reverse
case h2::t2 if(leq(h1._1, h2)) => helper(list2, t2, acc1, acc2)(leq)
case h2::t2 => helper(list2, t2, false, acc2)(leq)
}
}
}
}
helper(list1, list1.head._2, true, List())(P)
}
val list1 = List((1,List(1,2,3)), (2, List(2,3)), (3, List(3,2)), (4, List(4,5,6,3)))
println(checkPeq(list1)(_<=_))
我有一个尾递归函数 returns List[Boolean],在本例中为 List(true, true, false, false)。它正在工作,但问题是我需要在没有 ._ 或 .head 的情况下完成它,最好没有索引(bcz 我可以轻松地用 (0) 替换此函数中的 .head )。我需要通过模式匹配来完成,但我不知道如何开始。我还从我的老师那里得到了一个提示,更换它应该非常快。如果有任何关于如何处理该问题的提示,我将不胜感激。
以下遗漏部分应该可以帮助您解决其余问题:
匹配列表的模式
val l = List(2,3)
l match {
case Nil => "the list is empty"
case head :: Nil => "the least has one element"
case head :: tail => "thie list has a head element and a tail of at least one element"
}
匹配元组的模式
val t = (75, "picard")
t match {
case (age, name) => s"$name is $age years old"
}
匹配元组列表的模式
val lt = List((75, "picard"))
lt match {
case Nil => "the list is empty"
case (name, age) :: Nil => "the list has one tuple"
case (name, age) :: tail => "the list has head tuple and a tail of at least another tuple"
}
匹配元组列表的元组的模式
val lt = List((75, "picard"))
val ct = List((150, "Data"))
(lt, ct) match {
case (Nil, Nil) => "tuple of two empty lists"
case ((name, age) :: Nil, Nil) => "tuple of a list with one tuple and another empty list"
case (Nil, (name, age) :: Nil) => "tuple of an empty list and another list with one tuple"
case ((name, age) :: tail, Nil) => "tuple of list with head tuple and a tail of at least another tuple, and another empty list"
case _ => "and so on"
}
注意模式是如何组成的。
一个解决方案是简单地同时匹配外部 A
列表和内部 B
列表,即作为单个模式的一部分。
def checkPeq[A,B](in: List[(A,List[B])])(pred: (A,B) => Boolean): List[Boolean] = {
@annotation.tailrec
def loop(aLst :List[(A,List[B])], acc :List[Boolean]) :List[Boolean] =
aLst match {
case Nil => acc.reverse //A list done
case (_,Nil) :: aTl => loop(aTl, true::acc) //B list done
case (a,b::bTl) :: aTl => //test a and b
if (pred(a,b)) loop((a,bTl) :: aTl, acc)
else loop(aTl, false::acc)
}
loop(in, List.empty[Boolean])
}
def checkPeq[A,B](list1: List[(A, List[B])])( P: (A,B) => Boolean): List[Boolean] = {
def helper[A,B](list2: List[(A, List[B])], list3: List[B], acc1: Boolean, acc2: List[Boolean])(leq:(A,B) => Boolean): List[Boolean] = {
list2 match {
case h1::t1 => {
list3 match {
case Nil if t1!=Nil => helper(t1, t1.head._2, true, acc1::acc2)(leq)
case Nil => (acc1::acc2).reverse
case h2::t2 if(leq(h1._1, h2)) => helper(list2, t2, acc1, acc2)(leq)
case h2::t2 => helper(list2, t2, false, acc2)(leq)
}
}
}
}
helper(list1, list1.head._2, true, List())(P)
}
val list1 = List((1,List(1,2,3)), (2, List(2,3)), (3, List(3,2)), (4, List(4,5,6,3)))
println(checkPeq(list1)(_<=_))
我有一个尾递归函数 returns List[Boolean],在本例中为 List(true, true, false, false)。它正在工作,但问题是我需要在没有 ._ 或 .head 的情况下完成它,最好没有索引(bcz 我可以轻松地用 (0) 替换此函数中的 .head )。我需要通过模式匹配来完成,但我不知道如何开始。我还从我的老师那里得到了一个提示,更换它应该非常快。如果有任何关于如何处理该问题的提示,我将不胜感激。
以下遗漏部分应该可以帮助您解决其余问题:
匹配列表的模式
val l = List(2,3)
l match {
case Nil => "the list is empty"
case head :: Nil => "the least has one element"
case head :: tail => "thie list has a head element and a tail of at least one element"
}
匹配元组的模式
val t = (75, "picard")
t match {
case (age, name) => s"$name is $age years old"
}
匹配元组列表的模式
val lt = List((75, "picard"))
lt match {
case Nil => "the list is empty"
case (name, age) :: Nil => "the list has one tuple"
case (name, age) :: tail => "the list has head tuple and a tail of at least another tuple"
}
匹配元组列表的元组的模式
val lt = List((75, "picard"))
val ct = List((150, "Data"))
(lt, ct) match {
case (Nil, Nil) => "tuple of two empty lists"
case ((name, age) :: Nil, Nil) => "tuple of a list with one tuple and another empty list"
case (Nil, (name, age) :: Nil) => "tuple of an empty list and another list with one tuple"
case ((name, age) :: tail, Nil) => "tuple of list with head tuple and a tail of at least another tuple, and another empty list"
case _ => "and so on"
}
注意模式是如何组成的。
一个解决方案是简单地同时匹配外部 A
列表和内部 B
列表,即作为单个模式的一部分。
def checkPeq[A,B](in: List[(A,List[B])])(pred: (A,B) => Boolean): List[Boolean] = {
@annotation.tailrec
def loop(aLst :List[(A,List[B])], acc :List[Boolean]) :List[Boolean] =
aLst match {
case Nil => acc.reverse //A list done
case (_,Nil) :: aTl => loop(aTl, true::acc) //B list done
case (a,b::bTl) :: aTl => //test a and b
if (pred(a,b)) loop((a,bTl) :: aTl, acc)
else loop(aTl, false::acc)
}
loop(in, List.empty[Boolean])
}