FP:如何过滤List [A],这样它将包含除Option [A]以外的所有元素

时间:2017-07-20 16:46:13

标签: scala

这是更有教育意义的答案,因为我有工作解决方案,但我觉得应该有一些我错过的功能编程模式或概念,我想学习它。

假设我有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(_))? 谢谢!

5 个答案:

答案 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,它们很糟糕。