Reputation: 584
i am a new Scala programmer and I have a question on Scala Array pattern matching:
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)
}
}
}
Basically what i want to do is: when we have an Array of length longer than 2, if n(0)< h(1), call function recursively with a new Array of the head and whatever as the tail. otherwise call function with a new Array of the next and whatever as the tail. But this code gets me an error:
"error: missing parameter type for expanded function ((<x$1: error>) => x$1.$times) (in solution.scala)
countErased(Array(h,_*), acc+1)"
What is wrong?
Upvotes: 0
Views: 1279
Reputation: 40500
Your immediate problem is addressed in the other answer: you just need to give a name to the splat, like rest@_*
, and use that to refer to it.
I just want to second the advice from the comments, and mention that you should be using a List
rather that an array (you can have a wrapper function that calls countErased(array.toList, 0)
if that's convenient).
The match
in scala also looks much nicer and idiomatic with lists:
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
}
As a side note, one difference from your original implementation is that this one does not throw if one of the arrays happens to have fewer than two elements.
Upvotes: 2
Reputation: 51271
You're actually pretty close. You just need to remember that the sorted
variable is still available to you and it contains what you need to construct the next Array
.
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(h +: sorted.drop(2), acc+1)
else countErased( sorted.tail, acc)
}
As mentioned, it's pretty inefficient to manipulate arrays in this manner but if you're stuck with Array[Array[Int]]
this will work.
Upvotes: 1
Reputation: 7180
Welcome to the Scala community :)
I concur with other comments, Seq
and List
tend to be recommended since they're immutable (much preferable especially in a recursive setting) and efficient.
It's doable with Array
though, your code is almost working, all I had to add was giving a name to the _*
capture (that's what the rest@
is doing), which is then an instance of Seq[Array]
, s.t. I could re-use it in the recursive call:
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)
}
}
}
Upvotes: 2