Search code examples
scalalistseq

Scala way to set object field value if null in a Seq/List


What is the nicest way to iterate over Scala Seq/List (or other similar collection for that matter) of objects and set the value of a specific object field in case they are null?

For example, a case class:

case class AmazingData(age: Int, name: String)

val ad1 = AmazingData(12, "bar")
val ad2 = AmazingData(12, "foo")
val ad3 = AmazingData(12, null)

val alotOfAmazingData: Seq[AmazingData] = Seq(ad1, ad2, ad3)

Now I want to iterate over alotOfAmazingData and set the name value for the ones that have null.


Solution

  • If you'd like to keep the complete collection in tact, you can only use a map and contain the predicate inside:

    val allWithNonNull = 
      alotOfAmazingData
        .map(amazing => if (amazing.name == null) amazing.copy(name = "Some Name") else amazing)
    

    If you only care about the null names, you can filter out instances that have the name field set and leave only those with null, and then map over then and set them via copy:

    val nonNullNames = 
      alotOfAmazingData.withFilter(_.name != null)
                       .map(_.copy(name = "Some Name"))
    

    Or using collect:

    val nonNullNames = 
      alotOfAmazingData
        .collect { 
           case amazingData if amazingData.name == null =>
         amazingData.copy(name = "Some Name") 
         }
    

    Although I would encourage you to not use null at all, and use Option[String] instead, making your case class look like this:

    case class AmazingData(age: Int, name: Option[String])
    

    And when you want to work with the optional name field, you can use map and the likes.