2015-09-03 26 views
0

想要获得更多的FP方式开发。在我的情况下,DAO可以返回Object或None。 但我如果不存在的所有对象更多FP方式代替if/else

实现这样

def get(...): String = { 
    val user1 = UserDAO.getUser(...) 
    val user1 = UserDAO.getUser(...) 
    val userN = UserDAO.getUser(...) 

if (user1.isEmpty || ser2.isEmpty || ...) { 
return "error" 
} else { 
... 
} 

它可以实现更多的功能性的方式保证。没有混乱如果/其他?

BR!

+1

一个if-else表达式是不是“不FP “,但要摆脱不必要的”回报“。 –

回答

2

考虑

if (Seq(user1,user2,userN).exists(_.isEmpty)) "error" 
else "" 

随着existsisEmpty我们检查是否任何用户没有定义。这种方法会暂停迭代Seq,因为遇到谓词的第一项。

3

让你传递给的getUser的参数列表,并使用mapforall

val userIds = List(...) 
val dbUsers = userIds.map(UserDAO.getUser) 

,如果你不想使用if/else语句可以做到这一点,虽然它让人感觉有点倒过来,可能完全模糊了你的意图:

dbUsers.collectFirst { case user if user.isEmpty => "error" } getOrElse { "ok" } 

然而,据我所知的if/else是不是真的那么多当在FP(或中阶开发商至少)皱着眉头,所以你可以为它写在一个更具表现力,也简明的方式:

if (dbUsers.forall(_.nonEmpty)) "ok" else "error" 

,或者在反逻辑:

if (dbUsers.exists(_.isEmpty)) "error" else "ok" 
0

可以使用的,修真flatmap在所有3 Option[User]并指定所有3个用户存在会发生什么。

然后使用getOrElse指定应该发生什么,如果任何这些用户的是一个None

def get(...): String = { 
    val namesOpt = for { 
     u1 <- UserDAO.getUser(...) 
     u2 <- UserDAO.getUser(...) 
     u3 <- UserDAO.getUser(...) 
    } yield u1.name + u2.name + u3.name 

    namesOpt getOrElse "error" 
} 
0
val users = /* collection of Option[User] types */ 
users.find(!_.isDefined).fold("ok") { _ => "error" } 

或..

users.find(_.isEmpty).fold("ok") { _ => "error" } 
+0

'!_。isDefined'可以被重写为'_.isEmpty'。 – VasyaNovikov