Scala Option 和 flatMap

问题描述 投票:0回答:3

我正在尝试掌握“Scala 方式”工作的窍门,所以我想知道下面的代码是否是在这种情况下应该如何完成的事情。

所以我有实体用户和公司(使用 LiftWeb 映射器映射)。 User 具有包含选项 [User] 的 currentUser,而 Company 具有包含 Option[Company] 的 currentCompany。为了比较当前用户是否是当前公司的所有者,我正在执行以下操作:

Company.currentCompany.map{_.owner.get == User.currentUser.map{_.id.get}.openOr(-1) }.openOr(false)

它有效,但不知何故感觉有点冗长。好吗?不是吗?还有更好的想法吗? 谢谢!

scala monads
3个回答
10
投票

[`我已经从堆栈溢出中删除了所有答案,因为我不想为提取性、剥削性、“人工智能”服务的培训做出贡献。抱歉。]


6
投票
使用理解确实是解决方案,实际上......或

flatMap

但可读性较差

回想一下,每个生成器都使用 Monadic

flatMap

Option
 函数进行绑定,除了最后一个被映射的生成器(如任何 
for
yield
)。这是一个关于底层概念的很好的幻灯片
Monad

因此,for 理解用于传递所有步骤,同时它们未编码为失败状态(

None

 表示 
Option
)。

这是一个完整的示例,每个选项(for 和 flatMap)都有四个测试(四种基本情况)

case class User(id: String) { } object User { def currentUser(implicit me: Option[User]): Option[User] = me } case class Company(owner: Option[User]) { } object Company { def currentCompany(implicit myCompany: Option[Company]): Option[Company] = myCompany } object Test extends App { test1() test2() test3() test4() test5() test6() test7() test8() def test1() { implicit val me: Option[User] = None implicit val myCompany: Option[Company] = None val v: Boolean = (for { c <- Company.currentCompany u <- User.currentUser o <- c.owner if o.id == u.id } yield true) getOrElse false println(v) } def test2() { implicit val me: Option[User] = Some(User("me")) implicit val myCompany: Option[Company] = None val v: Boolean = (for { c <- Company.currentCompany u <- User.currentUser o <- c.owner if o.id == u.id } yield true) getOrElse false println(v) } def test3() { implicit val me: Option[User] = None implicit val myCompany = Some(Company(me)) val v: Boolean = (for { c <- Company.currentCompany u <- User.currentUser o <- c.owner if o.id == u.id } yield true) getOrElse false println(v) } def test4() { implicit val me: Option[User] = Some(User("me")) implicit val myCompany = Some(Company(me)) val v: Boolean = (for { c <- Company.currentCompany u <- User.currentUser o <- c.owner if o.id == u.id } yield true) getOrElse false println(v) } def test5() { implicit val me: Option[User] = None implicit val myCompany: Option[Company] = None val v:Boolean = Company.currentCompany.flatMap(c => User.currentUser.flatMap( u => c.owner.map(o => if (u.id == o.id) true else false))) getOrElse false println(v) } def test6() { implicit val me: Option[User] = Some(User("me")) implicit val myCompany: Option[Company] = None val v:Boolean = Company.currentCompany.flatMap(c => User.currentUser.flatMap( u => c.owner.map(o => if (u.id == o.id) true else false))) getOrElse false println(v) } def test7() { implicit val me: Option[User] = None implicit val myCompany = Some(Company(me)) val v:Boolean = Company.currentCompany.flatMap(c => User.currentUser.flatMap( u => c.owner.map(o => if (u.id == o.id) true else false))) getOrElse false println(v) } def test8() { implicit val me: Option[User] = Some(User("me")) implicit val myCompany = Some(Company(me)) val v:Boolean = Company.currentCompany.flatMap(c => User.currentUser.flatMap( u => c.owner.map(o => if (u.id == o.id) true else false))) getOrElse false println(v) } }
    

0
投票
鉴于:

Case class user(name:String) Case class company(owner:Option[User]) Val currentcompany=company(Some("Karl")) Val currentuser=Some(user("Karl"))

可能的解决方案:

currentcompany.foldLeft(false) { case (a,b) => currentuser.isDefined && b.owner == currentUser.get }
    
© www.soinside.com 2019 - 2024. All rights reserved.