CustardBun
CustardBun

Reputation: 3867

In Scala, only add items to Map if Optional values are present

I'm new to scala and I'm trying to do something like this in a clean way.

I have a method that takes in several optional parameters. I want to create a map and only add items to the map if the optional parameter has a value. Here's a dummy example:

def makeSomething(value1: Option[String], value2: Option[String], value3: Option[String]): SomeClass = {
  val someMap: Map[String, String] = 
     value1.map(i => Map("KEY_1_NAME" -> i.toString)).getOrElse(Map())
}

In this case above, we're kind of doing what I want but only if we only care about value1 - I would want this done for all of the optional values and have them put into the map. I know I can do something brute-force:

def makeSomething(value1: Option[String], value2: Option[String], value3: Option[String]): SomeClass = {
  // create Map
  // if value1 has a value, add to map
  // if value2 has a value, add to map 
  // ... etc
}

but I was wondering if scala any features that would help me able to clean this up.

Thanks in advance!

Upvotes: 3

Views: 2532

Answers (2)

Dima
Dima

Reputation: 40510

.collect is one possibility. Alternatively, use the fact that Option is easily convertible to a Seq:

 value1.map("KEY1" -> _) ++ 
 value2.map("KEY2" -> _) ++ 
 value3.map("KEY3" -> _) toMap

Upvotes: 4

Tzach Zohar
Tzach Zohar

Reputation: 37852

You can create a Map[String, Option[String]] and then use collect to remove empty values and "extract" the present ones from their wrapping Option:

def makeSomething(value1: Option[String], value2: Option[String], value3: Option[String]): SomeClass = {
  val someMap: Map[String, String] = 
    Map("KEY1" -> value1, "KEY2" -> value2, "KEY3" -> value3)
     .collect { case (key, Some(value)) => key -> value }

  // ...
}

Upvotes: 8

Related Questions