Kishori
Kishori

Reputation: 151

Substitute value of an attribute based on conditions in scala

I am working on an API module in scala which queries DB and returns the fetched data in JSON format as the response. For a particular attribute in the JSON(whose type is Option[String]) , I need to alter the value fetched from DB based on certain conditions. Currently , my JSON response looks like this:

.....
{
    "id": "1",
    "name": "abc",
    "osType": "windows",        
    "osVersion": "10.0.14393"        
},
{
    "id": "2",
    "name": "xyz",
    "osType": "ubuntu",        
    "osVersion": "18.04"
},
{
    "id": "3",
    "name": "pqr",
    "osType": "windows",        
    "osVersion": "6.1.7601"
},
......

I need to substitute the following values for osVersion for records with "osType": "windows"

if osVersion = 10.0.14393 , then Windows Server 2016
if osVersion starts with 6.1 , then Windows Server 2008 R2  

So that desired output looks like this:

.....
{
    "id": "1",
    "name": "abc",
    "osType": "windows",        
    "osVersion": "Windows Server 2016"        
},
{
    "id": "2",
    "name": "xyz",
    "osType": "ubuntu",        
    "osVersion": "18.04"
},
{
    "id": "3",
    "name": "pqr",
    "osType": "windows",        
    "osVersion": "Windows Server 2008 R2"
},
......

I tried using if-else and pattern-matching , but am unable to substitute correctly as the type is Option[String]. This is how I tried: (1)

def translateOSVersion (osType :Option[String] ,osVersion : Option[String]):Option[String] ={
          if (osType == "windows"){
            val version = if (osVersion =="10.0.14393")
              {
                Some("Windows Server 2016")
              }
            else {osVersion}
            version
            }
        }

        val oSVersion = translateOSVersion(ostr("osType") ,ostr("osVersion") )

        <modelJSON>(id, name, ostr("osType"), oSVersion)

(2)

 def translateOSVersion (osType :Option[String] ,osVersion : Option[String]) ={
  if (osType == "windows"){
    val version = if (osVersion =="10.0.14393") Some("Windows Server 2016")
    else osVersion
    }
}

val oSVersion = Some(translateOSVersion(ostr("osType") ,ostr("osVersion") ).toString)
  <modelJSON>(id, name, ostr("osType"), oSVersion)

(3)

def translateOSVersion (osType :Option[String] ,osVersion : Option[String]) ={
      if (osType == "windows"){
        osVersion match {
          case Some("10.0.14393") => "Windows Server 2016"
          case x =>x
        }
        }
    }
val oSVersion = Some(translateOSVersion(ostr("osType") ,ostr("osVersion") ).toString)
      <modelJSON>(id, name, ostr("osType"), oSVersion)

All the approaches do not result in desired result. Kindly help here.

Upvotes: 0

Views: 56

Answers (1)

Tim
Tim

Reputation: 27356

Something like this should work:

def translateOSVersion(osType: Option[String], osVersion: Option[String]): Option[String] =
  (for {
    ot <- osType if ot == "windows"
    ov <- osVersion
  } yield {
    if (ov == "10.0.14393") {
      "Windows Server 2016"
    } else if (ov.startsWith("6.1")) {
      "Windows Server 2008 R2"
    } else {
      ov
    }
  }) orElse osVersion

This is how it works:

The for statement creates a new Option[String] representing the updated version number, or None if there is no change. It works by extracting the two Option values into ot for the OS Type and ov for the OS Version. If either of the Options is None it will return None, and it will also return None if the OS type is not "windows". If all these tests pass, the yield expression computes the new version based on these values. In this case the for will return Some(x) where x is the value of the yield expression.

The orElse expression will return the first value if it is Some(x), otherwise it will return the second value. So if the result of the for is Some(x) then it is returned as the result of the function. If the for returns None then the original value is returned as the result.


This is a more prosaic version that is probably more suitable, though less fun!

def translateOSVersion(osType: Option[String], osVersion: Option[String]): Option[String] =
  if (osType.contains("windows")) {
    if (osVersion.contains("10.0.14393")) {
      Some("Windows Server 2016")
    } else if (osVersion.exists(_.startsWith("6.1"))) {
      Some("Windows Server 2008 R2")
    } else {
      osVersion
    }
  } else {
    osVersion
  }

Upvotes: 2

Related Questions