0

Scala create the Map from an list of Option emelents?

myMap = (0 to r.numRows - 1).map { i =>
  if (Option(r.getValue(i,"Name")).isDefined)
    (r.getValue(i, "Name")) -> (r.getValue(i, "isAvailable").toString)
}.toMap
foo(myMap) //here At this point, I'm geting the exception

I have tried above code but not compiling:

Exception:
Error:(158, 23) Cannot prove that Any <:< (T, U).
                }.toMap
                  ^
user1079341
  • 111
  • 7

1 Answers1

1

Maybe try this code:

val myMap = (0 until r.numRows) flatMap { i =>
  for {
    name <- Option(r.getValue(i, "Name"))
    available = r.getValue(i, "isAvailable").toString
  } yield (name, available)
}.toMap
foo(myMap)

Your problem is most likely that you use if without else, and if is an expression in scala, which means it evaluates to something.

if (2 > 3) true

is equivalent to

if (2 > 3) true else ()

so the type is the common supertype of Unit and Boolean which is Any and this is the error you get.

Note that you can replace to and -1 with until which does the same thing but is more readable.

You shouldn't really check Option with isDefined and perform action on result if that's true, to do this you use map operation.

To explain my implementation a little: the for part will evaluate to Option[(String, String)], and will contain your tuple if "Name" key was present, otherways None. Conceptually, flatMap will first change your range of indices to a sequence of Option[(String, String)], and then flatten it, i.e. remove all Nones and unwrap all Somes.

If you want to check "isAvailable" for null as well, you can do similar thing

for {
  name      <- Option(r.getValue(i, "Name"))
  available <- Option(r.getValue(i, "isAvailable"))
} yield (name, available.toString)
Łukasz
  • 8,555
  • 2
  • 28
  • 51