问题描述
我是一个新的 Scala 程序员,我有一个关于 Scala 数组模式匹配的问题:
def counterased(sorted: Array[Array[Int]],acc: Int): Int = {
sorted match{
case Array() | Array(_) => acc
case Array(h,n,_*) =>
if(n(0) < h(1)){
counterased(Array(h,_*),acc+1)
}else{
counterased(Array(n,acc)
}
}
}
基本上我想要做的是:当我们有一个长度大于 2 的数组时,如果 n(0)
"error: missing parameter type for expanded function ((<x$1: error>) => x$1.$times) (in solution.scala)
counterased(Array(h,acc+1)"
怎么了?
解决方法
欢迎加入 Scala 社区 :)
我同意其他评论,Seq
和 List
倾向于被推荐,因为它们是不可变的(尤其是在递归设置中更可取)且高效。
虽然使用 Array
是可行的,但您的代码几乎可以运行,我所要做的就是为 _*
捕获命名(这就是 rest@
正在执行的操作),即然后是 Seq[Array]
的实例,st我可以在递归调用中重新使用它:
def countErased(sorted: Array[Array[Int]],acc: Int): Int = {
sorted match {
case Array() | Array(_) => acc
case Array(h,n,rest@_*) =>
if (n(0) < h(1)) {
countErased(h +: rest.toArray,acc + 1)
} else {
countErased(n +: rest.toArray,acc)
}
}
}
,
您的直接问题已在另一个答案中解决:您只需要为 splat 命名,例如 rest@_*
,并使用它来引用它。
我只想从评论中获得建议,并提到您应该使用 List
而不是数组(如果方便,您可以使用包装函数调用 countErased(array.toList,0)
)。
scala 中的 match
与列表一起看起来也更好,更地道:
def countErased(sorted: List[Array[Int]],acc: Int) = sorted match {
case h@Array(_,x,_*) :: Array(y,_*) :: tail if y < x => countErased(h :: tail,acc+1)
case _ :: n :: tail => countErased(n :: tail,acc)
case _ => acc
}
作为旁注,与您的原始实现的一个不同之处在于,如果其中一个数组碰巧少于两个元素,则该实现不会抛出。
,你实际上很接近。您只需要记住 sorted
变量仍然可供您使用,它包含构建下一个 Array
所需的内容。
def countErased(sorted: Array[Array[Int]],acc: Int): Int =
sorted match {
case Array() | Array(_) => acc
case Array(h,_*) =>
if (n(0) < h(1)) countErased(h +: sorted.drop(2),acc+1)
else countErased( sorted.tail,acc)
}
如前所述,以这种方式操作数组的效率非常低,但如果您坚持使用 Array[Array[Int]]
,这将起作用。