在一个光滑的查询中,我有:
def getAbc(userId: Option[Int], levelId: Option[Int]): List[User] = {
val q = for {
m <- users if m.approved &&
userId.isDefined && m.userId ==== userId.get && levelId.isDefined && m.levelId === levelId.get
} yield m
q.list()
}
我不喜欢我在上面使用isDefined和.get,我该如何删除它们?
val user: Option[User] = ....
if(user.isDefined) {
val productSales:List[Product] = getProducts(user.get.id)
val isBoss = (user.get.levelId.isDefined && (user.get.levelId.get == 10))
}
在上面,如果是isDefined检查,我有2个级别,我该如何绕过这种类型的模式?
答案 0 :(得分:1)
scala> val userId = Some(1)
userId: Some[Int] = Some(1)
scala> val levelId = Some(2)
levelId: Some[Int] = Some(2)
scala> for { u <- userId
| l <- levelId
| q = u + l // This would be your query
| } yield q
res0: Option[Int] = Some(3)
答案 1 :(得分:1)
你可以利用理解(正如上面已经提到的其他答案):
val q: Option[List[User]] = for {
uId <- userId
lvlId <- levelId
m <- users
if m.approved && m.userId ==== uId && m.levelId === lvlId
} yield m
q.getOrElse(Nil)
和第二个基本相同:
val levelCheck: Option[Int] = for {
u <- user
lvlId <- u.levelId
if lvlId == 10
} yield lvlId
val isBoss: Boolean = levelCheck.isDefined
val productSales:List[Product] = user.map(u => getProducts(u.id)).getOrElse(Nil)
答案 2 :(得分:0)
Option
是一个monad(例如, - http://www.scala-lang.org/old/node/7326)
因此您可以使用map/flatMap/filter
或for-yield
。
以下是一些示例,您无需检查isDefined
或get
即可执行操作。
scala> val a : Option[String] = Some("John")
a: Option[String] = Some(John)
scala> for( x <- a ) yield println(x)
John
res6: Option[Unit] = Some(())
scala> a.isDefined
res7: Boolean = true
scala> val b : Option[String] = None
b: Option[String] = None
scala> b.isDefined
res8: Boolean = false
scala> for ( x <- b ) yield print(x)
res9: Option[Unit] = None
scala> val names : List[Option[String]] = List(Some("John"), None, Some("James") )
names: List[Option[String]] = List(Some(John), None, Some(James))
scala> val validNames = for { name <- names; n <- name } yield { n }
validNames: List[String] = List(John, James)