Search code examples
scalaintdoubleany

Scala Cast List of Any to list of Int


Given a List of Any:

val l = List(2.9940714E7, 2.9931662E7, 2.993162E7, 2.9931625E7, 2.9930708E7, 2.9930708E7, 2.9931477E7)

I need to cast each item to Int.

Works:

l(1).asInstanceOf[Double].toInt

Not:

l.foreach{_.asInstanceOf[Double].toInt}
> java.lang.String cannot be cast to java.lang.Double

If

l.foreach{_.asInstanceOf[String].toDouble.toInt}
> java.lang.Double cannot be cast to java.lang.String

I'm new to Scala. Please tell me what I'm missing. Why I can cast one item from list, but can't do this via iterator? Thanks!


Solution

  • It seems as if a String somehow ended up in your List l.

    Given a list that is structured like this (with mixed integers, Doubles, and Strings):

    val l = List[Any](2.9940714E7, 2.9931625E7, "2.345E8", 345563)
    

    You can convert it to list of integers as follows:

    val lAsInts = l.map {
      case i: Int => i
      case d: Double => d.toInt
      case s: String => s.toDouble.toInt
    }
    
    println(lAsInts)
    

    This works for Doubles, Ints and Strings. If it still crashes with some exceptions during the cast, then you can add more cases. You can, of course, do the same in a foreach if you want, but in this case it wouldn't do anything, because you don't do anything in the body of foreach except casting. This has no useful side-effects (e.g. it prints nothing).

    Another option would be:

    lAsInts = l.map{_.toString.toDouble.toInt}
    

    This is in a way even more forgiving to all kind of weird input, at least as long as all values are "numeric" in some sense.

    However, this is definitely code-smell: how did you get a list with such a wild mix of values to begin with?