根据scala中的条件替换属性的值

Substitute value of an attribute based on conditions in scala

我正在 scala 中开发一个 API 模块,它查询数据库并 returns 以 JSON 格式获取的数据作为响应。 对于 JSON(其类型为 Option[String]) 中的特定属性,我需要根据特定条件更改从数据库中获取的值。 目前,我的 JSON 回复如下所示:

.....
{
    "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"
},
......

我需要将 osVersion 的以下值替换为 "osType": "windows"

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

因此所需的输出如下所示:

.....
{
    "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"
},
......

我试过使用 if-elsepattern-matching ,但是我无法正确替换,因为类型是 Option[String]。 这就是我尝试的方式: (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)

所有的方法都没有得到预期的结果。 请在这里帮忙。

像这样的东西应该可以工作:

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

这是它的工作原理:

for 语句创建一个新的 Option[String] 表示更新后的版本号,如果没有变化则为 None。它通过将两个 Option 值提取到 OS 类型的 ot 和 OS 版本的 ov 中来工作。如果 Option 中的任何一个是 None,它将 return None,如果 OS,它也会 return None类型不是 "windows"。如果所有这些测试都通过,yield 表达式将根据这些值计算新版本。在这种情况下,for 将 return Some(x) 其中 xyield 表达式的值。

如果 orElse 表达式是 Some(x),则表达式将 return 第一个值,否则它将 return 第二个值。因此,如果 for 的结果是 Some(x),那么它将 returned 作为函数的结果。如果 for returns None 则原始值被 returned 作为结果。


这是一个更平淡无奇的版本,可能更适合,但不那么有趣!

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
  }