使用scala中的选项(最佳实践)
我编写了一个方法,通过执行api调用并添加丰富的数据来丰富person数据 所以我有这个案例课:使用scala中的选项(最佳实践),scala,scala-option,Scala,Scala Option,我编写了一个方法,通过执行api调用并添加丰富的数据来丰富person数据 所以我有这个案例课: case class Person(personData: PersonData, dataEnrichment: Option[DataEnrichment]) 我的方法假设返回这个case类 但是我以前很少有过滤器 如果person height不是“1.8米”,或者如果使用regex在bio中找不到personId,我想返回person,其中dataenrich=None 我的问题是人
case class Person(personData: PersonData, dataEnrichment: Option[DataEnrichment])
我的方法假设返回这个case类
但是我以前很少有过滤器
如果person height不是“1.8米”
,或者如果使用regex在bio中找不到personId,我想返回person
,其中dataenrich=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])
def enrichPersonObjWithApiCall(个人:个人)={
person.personData.height.map(u.equals(“1.8米”)匹配{
案例部分(正确)=>
val personId=person.personData.bio flatMap{comment=>
ExtractPersonidExists(注释)
}
拟人匹配{
案例部分(perId)=>
apiCall(perId)映射{apiRes=>
人(
person.personData,
数据浓缩=apiRes)
}
案例=>
未来成功人士(
person.personData,
数据浓缩=无)
}
案例=>
未来成功人士(
person.personData,
数据浓缩=无)
}
}
def extractPersonIdIfExists(personBio:String):选项[String]={
val personIdRegex:Regex=“”(?在这里,我试图让它更地道、更简短:
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))
)
}
基本上,这个想法是使用适当的map
,flatMap
,collect
一元链,而不是在适当的时候进行模式匹配。与艾维安的答案相同。我只会使用map
flatMap
和过滤器
def enrichPersonObjWithApiCall(person: Person) = {
person.personData.height
.filter(_ == "1.8 m")
.flatMap{_=>
val personId = person.personData.bio
.flatMap(extractPersonIdIfExists)
personId.map(
apiCall(_)
.map(apiRes => person.copy(dataEnrichment = apiRes))
)
}.getOrElse(Future.successful(person))
}
这对我来说更具可读性。使用for
是处理选项链的一种好方法
值:
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)))
def enrichPersonObjWithApiCall(个人:个人):未来[个人]=
(
为了{
高度