我有一个方法,我写的方法是通过执行api调用来增加人员数据并添加丰富的数据.
所以我有这个案例类:
case class Person(personData: PersonData, dataEnrichment: Option[DataEnrichment])
我的方法假设返回这个case类.
但之前我的过滤器很少,
如果人的身高不是“1.8米”,或者如果使用正则表达式在bio中找不到personId,我想返回具有dataEnrichment = None的人
我的问题是人身高和人自己是选项本身.
所以它看起来像这样:
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])
dosent似乎是scala最佳实践,就像那样执行它.你有更优雅的方式来获得相同的结果吗?
最佳答案 使用for是处理Option值链的好方法:
def enrichPersonObjWithApiCall(person: Person): Future[Person] =
(
for {
height <- person.personData.height if height == "1.8 m"
comment <- person.personData.bio
perId <- extractPersonIdIfExists(comment)
} yield {
apiCall(perId).map(Person(person.personData, _))
}
).getOrElse(Future.successful(Person(person.personData, None)))
这相当于map,flatMap和filter调用链,但更容易阅读.