Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

determine if T of Manifest[T] is a collection

currently i have this:

private def isCollectionLike[T](manifest: Manifest[T]):Boolean = {
   manifest.runtimeClass.toString.contains("scala.collection")
}

I don't like this solution, can you purpose a better one?

like image 397
Yosefki Avatar asked Dec 16 '13 08:12

Yosefki


1 Answers

Just callingClass#isAssignable should be enough:

def isCollectionLike[T](manifest: Manifest[T]):Boolean = {
  classOf[scala.collection.TraversableLike[_,_]].isAssignableFrom(manifest.runtimeClass)
}

Mandatory REPL test:

scala> isCollectionLike(manifest[List[Int]])
res17: Boolean = true

scala> isCollectionLike(manifest[String])
res18: Boolean = false

scala> isCollectionLike(manifest[scala.collection.SeqLike[Int,_]])
res19: Boolean = true

Note though that this won't work with arrays, for the simple reason that scala arrays now (since scala 2.8) map directly to the udnerlying JVM arrays, and as such do not inherit TraversableLike (If interested you can have a look at http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html).

scala> isCollectionLike(manifest[Array[String]])
res20: Boolean = false

So you'll have to handle it as a special case, or find a better way to test for a collection.

As a side note, these days there is an alternative to java reflection scala's own reflection api (and in addition Manifest is deprecated in favor of TypeTag), which has the immense advantage of understanding all the scala specific features (that Class instance retruned by runtimeClass does not know anything about scala). But it is also more complex, and (currently) not thread safe at all, which is a major limitation.

Plus in your case you will still have to handle arrays as a special case anyway.

like image 190
Régis Jean-Gilles Avatar answered Sep 30 '22 16:09

Régis Jean-Gilles