如何对数组进行scala模式匹配?

问题描述

我是一个新的 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 社区 :)

我同意其他评论,SeqList 倾向于被推荐,因为它们是不可变的(尤其是在递归设置中更可取)且高效。

虽然使用 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]],这将起作用。