1

I'm able to convert Option[String] to List[String] with the following code :

 def convertOptionToListString(a: Option[String]): List[String] = {
    return a.toList.flatMap(_.split(",")) // ex : ("value1", "value2", "value3", etc)
  }

But how can i convert Option[String] to List[Int] so at the end i can have list with integers : (1,3,5). My Option[String] will looks like this : Some("1,3,5")

Note that the values 1,3,5 comes from params.get("ids") sent from an url and params.get is an Option[String]

val params = request.queryString.map { case (k, v) => k -> v(0) }

Thanks

Artemis
  • 2,553
  • 7
  • 21
  • 36
user708683
  • 500
  • 3
  • 9
  • 26

4 Answers4

2

Scala 2.13 introduced String::toIntOption.

Combined with a flatMap, we can safely cast Strings into Ints and eliminate malformed inputs:

List("1", "2", "abc").flatMap(_.toIntOption)
// List[Int] = List(1, 2)
Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
1

If you want to convert List[String] to List[Int], skipping unparseable values, then you can use Try:

import scala.util.Try

List("1", "2", "3").flatMap(x => Try(x.toInt).toOption)
res0: List[Int] = List(1, 2, 3)

List("1", "2", "abc").flatMap(x => Try(x.toInt).toOption)
res1: List[Int] = List(1, 2)
Aivean
  • 10,692
  • 25
  • 39
  • A regex and `collect` would give you similar behavior: `val IntRe = "(\\d+)"; xs.collect { case Re(n) => n.toInt }` – dhg Apr 06 '16 at 05:20
0
val a: Option[String] = Some("1,3,5")
val l = a.toList.flatMap(_.split(",")).map(_.toInt)
dhg
  • 52,383
  • 8
  • 123
  • 144
  • Thank you dhg. I'm learning scala and this trick will help me a lot :) – user708683 Apr 05 '16 at 21:00
  • This will not work for non numeric characters _.toInt will throw NumberFormatException – franki3xe Apr 05 '16 at 21:02
  • @franki3xe, It also won't work if the input comes in pipe-delimited instead of comma-delimited, and it won't work if the input comes written in roman numerals, or in a secret code where integers are replaced by letters. If you know what the input looks like, why would you add unnecessary complexity to guard against something that's not going to happen? – dhg Apr 06 '16 at 05:15
  • Hey dhg, i wanted to up vote again but i'm not allowed for now !!! It's weird cause i already up voted yesteray and now it came to 0 !!! – user708683 Apr 06 '16 at 14:04
0

From where you are, you just need to map toInt over it. But your order of operations is kind of weird. It's like you're using toList just to satisfy the type. toList is one of those smelly functions where if you're using it you're probably abusing something.

The logic that reads the best is that if you have a Some, then process it, otherwise you just default to the empty list (I'm guessing):

option match {
  case Some(str) => str.split(",").map(_.toInt)
  case None => List()
}

Or:

option.map(_.split(",").map(_.toInt)).getOrElse(List())
MattPutnam
  • 2,927
  • 2
  • 17
  • 23