这是更有教育意义的答案,因为我有工作解决方案,但我觉得应该有一些我错过的功能编程模式或概念,我想学习它。
假设我有List[Player]
,其中Player
是案例类。我还有Option[Player]
,我想写一个方法,它将返回列表中的所有元素,除了Option
中包含的那个(可能!)。这是代码
case class Player(id:Long)
val players = List(Player(1), Player(2), Player(3))
var boss = None
def findAllExceptBoss = {
players.filter(boss != Some(_))
}
findAllExceptBoss.size should be (3)
var boss = Some(Player(1))
findAllExceptBoss.size should be (2)
所以,我的问题是 - 如何以更多功能的方式实现players.filter(boss != Some(_))
?
谢谢!
答案 0 :(得分:3)
如果老板没有被命名,你就不需要搜索列表,因此将搜索结果排除在外。
case class Player(id:Long)
val players = List(Player(1), Player(2), Player(3))
var boss: Option[Player] = None
def findAllExceptBoss = {
boss match {
case Some(b) => players.filter(b != _)
case None => players
}
}
findAllExceptBoss.size should be (3)
boss = Some(Player(1))
findAllExceptBoss.size should be (2)
答案 1 :(得分:2)
我经常发现fold()
是一个方便的Option
解包器。
boss.fold(players)(b => players.filterNot(_.id == b.id))
这样,如果您不必,则不会遍历players
。
答案 2 :(得分:1)
首先,你不应该有功能变化。我会做这样的事情:
def findAllExceptBoss(boss: Option[Player])(players: List[Player]): List[Player] = {
boss.map(b => players.filter(p => p != b).getOrElse(players)
}
findAllExceptBoss(None)(players).size should be (3)
这也可以让你做这样的事情:
def filterForSpecificBoss = findAllException(boss)
val filtered = filterForSpecificBoss(players)
答案 3 :(得分:1)
尊重你的方法定义,我会去:
def findAllExceptBoss=
for {
p <- players
b <- boss
if p != b
} yield p
答案 4 :(得分:1)
正确的方法是players.filterNot(boss.toSet)
另外,不要使用var
,它们很糟糕。