Reputation: 3562
I am trying to write a function that counts the number of elements in an array of elements of type T that pass a test of type T=>Boolean.
What I have so far is:
def countPass[T](elem: Array[T]) = {
var count = 0
for(x <- elem)
x match {
case x: T => count += 1
}
count
}
//TEST
println(countPass[Boolean](Array(true, 52, "test")))
I'm getting a couple of errors, the first one is:
combinators.scala:45: warning: abstract type pattern T is unchecked since
it is eliminated by erasure
case x: T => count += 1
^
The next error is:
combinators.scala:54: error: type mismatch;
found : Int(52)
required: Boolean
println(countPass[Boolean](Array(true, 52, "test")))
^
combinators.scala:54: error: type mismatch;
found : String("test")
required: Boolean
println(countPass[Boolean](Array(true, 52, "test")))
^
I'm not sure about whats happening with the first error, but with the second error it throws an exception anytime its not a boolean. I don't want that to happen because I'm just counting the amount of elements of type T are in the array.
Question: How should I refactor my code to fix both of these errors?
Upvotes: 0
Views: 1555
Reputation: 3863
You can directly use the method count
def countPass[T: ClassTag](elem: Array[Any]): Int = elem.count{
case _ : T => true
case _ => false
}
Upvotes: 0
Reputation: 3562
So I found out a way that works, but not exactly what I wanted.
def countPass[T](elem: Array[T]) = {
var count = 0
for(x <- elem)
x match {
case _: Boolean => count += 1
case _ => None
}
count
}
//TEST
println(countPass[Any](Array(true, 5, "test", false, false)))
The issue was I needed to pass Any into the array because I have different types in there. Additionally, I needed to change my cases a bit and add the default case.
This works perfectly, but I wanted something more like this. This does NOT work because of the same error specified above
def countPass[T](elem: Array[Any]) = {
var count = 0
for(x <- elem)
x match {
case _: T => count += 1 //Here is the error
case _ => None
}
count
}
//TEST
println(countPass[Boolean](Array(true, 5, "test", false, false)))
For some reason I cannot do _: T as my case or I get this error:
combinators.scala:44: warning: abstract type pattern T is unchecked since
it is eliminated by erasure
case _: T => count += 1
Upvotes: 0
Reputation: 1251
The trick is using ClassTag
. A better way to accomplish your request is as follows:
import scala.reflect.ClassTag
object Main extends App {
val array: Array[Any] = Array("string1", "string2", "string3", true, false, 13)
def countPass[Other: ClassTag](array: Array[Any]): Int = {
array.collect { case x: Other => x }.length
}
println(s"countPass String = ${countPass[String](array)}")
println(s"countPass Boolean = ${countPass[Boolean](array)}")
println(s"countPass Int = ${countPass[Int](array)}")
}
You can read this to learn more about ClassTag
and TypeTag
Upvotes: 7