2014-12-02 21 views
0

在一個漂亮的查詢我:如何去除.isDefined在下面的斯卡拉片斷

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並在上面不用彷徨,我該怎麼刪除?

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)) 

} 

在上面,我有2個級別,如果isDefined檢查,我怎麼能繞過這種類型的模式?

+1

注意'opt.isDefined && opt.get == x'等效於'opt.exists(_ == x)'。 – 2014-12-02 03:20:40

+0

...相當於'opt.contains(x)',對嗎? – dhg 2014-12-02 03:51:31

+0

@dhg好的,但是'==='不能使用,等等。 – 2014-12-02 04:19:30

回答

0

Option是單子(例如, - http://www.scala-lang.org/old/node/7326

所以你可以使用map/flatMap/filterfor-yield

以下是一些示例,您可以在不檢查isDefinedget的情況下執行操作。

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) 
+1

爲什麼這會被投票? – Jonoabroad 2014-12-02 03:21:47

+2

我不確定這是一個非常有用的答案。在這個問題中沒有任何跡象表明「Option」是一個monad「將會成爲OP的有用信息,列出一些你可以用Option來做的事情並不會更好。 – 2014-12-02 03:23:19

+0

爲什麼(...)產量println? for()println會做,而不會產生未使用(並且無法使用)的結果 – Suma 2014-12-02 09:37:07

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) 
+0

以上顯示瞭如何避免.isDefined和.get看到Soumya Simanta答案爲何以及爲什麼。 – Jonoabroad 2014-12-02 03:26:58

+0

謝謝,但只是提及,我想返回一個列表[用戶]不是一個選項。 – Blankman 2014-12-02 15:04:43

+0

實際上這不起作用。在comp之後。 q變量沒有像頂級查詢q.sortBy和q.list() – Blankman 2014-12-02 15:19:44

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) 
+0

通常的方法,它返回一個列表[用戶]不是一個選項[列表[用戶]] – Blankman 2014-12-02 15:04:10

+0

你是什麼意思的頂級查詢?或者什麼是返回一個'List [User]'? – 3x14159265 2014-12-02 18:14:07