使用Scala中的选项(最佳做法)

MNY*_*MNY 5 scala scala-option

我写了一种方法,可以通过执行api调用来丰富个人数据并添加丰富的数据。

所以我有这个案例类:

   case class Person(personData: PersonData, dataEnrichment: Option[DataEnrichment])
Run Code Online (Sandbox Code Playgroud)

我的方法假设要返回此case类。

但我之前没有几个过滤器

如果人身高不是,"1.8 m"或者如果使用正则表达式未在生物中找到personId,我想返回PersondataEnrichment = None

我的问题是,人身高和personId本身就是选项。

所以看起来像这样:

   def enrichPersonObjWithApiCall(person: Person) = {

      person.personData.height.map(_.equals("1.8 m")) match {
        case Some(true) =>
          val personId = person.personData.bio flatMap { comment =>
            extractPersonIdIfExists(comment)
          }
          personId match {
            case Some(perId) =>
              apiCall(perId) map { apiRes =>
                Person(
                  person.personData,
                  dataEnrichment = apiRes)
              }
            case _ =>
              Future successful Person(
                person.personData,
                dataEnrichment = None)
          }
        case _ =>
          Future successful Person(
            person.personData,
            dataEnrichment = None)
      }
    }

    def extractPersonIdIfExists(personBio: String): Option[String] = {
      val personIdRegex: Regex = """(?<=PersonId:)[^;]+""".r
      personIdRegex.findFirstIn(personBio)
    }

    def apiCall(personId: String): Future[Option[DataEnrichment]] = {
      ???
    }

    case class DataEnrichment(res: Option[String])

    case class PersonData(name: String, height: Option[String], bio: Option[String])
Run Code Online (Sandbox Code Playgroud)

这样做似乎是scala的最佳实践。您是否有更优雅的方法来达到相同的结果?

Aiv*_*ean 0

在这里,我尝试让它更惯用、更简短:

def enrichPersonObjWithApiCall(person: Person) = {
  person.personData.height.collect {
    case h if h == "1.8 m" =>
      val personId = person.personData.bio.flatMap(extractPersonIdIfExists)

      personId.map(
        apiCall(_)
          .map(apiRes => person.copy(dataEnrichment = apiRes))
      )
  }.flatten.getOrElse(
    Future.successful(person.copy(dataEnrichment = None))
  )
}
Run Code Online (Sandbox Code Playgroud)

基本上,这个想法是在适当的时候使用适当的一元链map, flatMap,collect而不是模式匹配。