2016-03-07 22 views
0

试图优化下一段代码:阶:代码优化:从列表中找到最大值项目或返回None如果等于]

private val players = scala.collection.mutable.ListBuffer.empty[Player] 

private def MaxDice(p1: Player, p2: Player): Player = if (p1.LastDice > p2.LastDice) p1 else p2 

private def MinDice(p1: Player, p2: Player): Player = if (p1.LastDice < p2.LastDice) p1 else p2 

def NextPlayer() : Option[Player] = { 
    val maxPlayer = this.players.reduceLeft(MaxDice) 
    val minPlayer = this.players.reduceLeft(MinDice) 
    if (maxPlayer.LastDice == minPlayer.LastDice) 
     None 
    else 
     Option(maxPlayer) 
} 

有没有办法在更复杂的方式来做到这一点?

+0

换句话说,你设法找到2名球员,其中一个最小的'LastDice'值,另一个是最大的。如果这两个玩家是同一个玩家,则返回'None',否则返回最大的LastDice值。我的理解是否正确? – Haspemulator

+0

是的,这是正确的。抱歉不清楚问题。 – Pavel

回答

3

如果你需要做的比较是应用程序的其他地方,你可以提取OrderingPlayer的同伴对象:

Welcome to Scala version 2.11.7 (OpenJDK 64-Bit Server VM, Java 1.8.0_66-internal). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> :paste 
// Entering paste mode (ctrl-D to finish) 


case class Player(lastDice: Int) 

object Player { 
    implicit val ordering: Ordering[Player] = Ordering.by(_.lastDice) 
} 

val players = List(Player(2), Player(2)) 

players.max == players.min 

// Exiting paste mode, now interpreting. 

defined class Player 
defined object Player 
players: List[Player] = List(Player(2), Player(2)) 
res0: Boolean = true 

附录:

另一个要考虑的是列表的大小。如果列表为空maxmin会抛出异常:

def min[B >: A](implicit cmp: Ordering[B]): A = { 
    if (isEmpty) 
    throw new UnsupportedOperationException("empty.min") 

    reduceLeft((x, y) => if (cmp.lteq(x, y)) x else y) 
} 

def max[B >: A](implicit cmp: Ordering[B]): A = { 
    if (isEmpty) 
    throw new UnsupportedOperationException("empty.max") 

    reduceLeft((x, y) => if (cmp.gteq(x, y)) x else y) 
} 

如果列表中只有一名球员,你的逻辑将错误地给你None。要将所有这些考虑在内,最简单的事情可能是使用排序列表。

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

case class Player(lastDice: Int) 

object Player { 
    implicit val orderingDescending: Ordering[Player] = 
    Ordering.fromLessThan(_.lastDice > _.lastDice) 

    def nextPlayer(players: List[Player]): Option[Player] = { 
    val sorted = players.sorted 
    sorted match { 
     case first :: Nil => Some(first) 
     case first :: second :: _ if first.lastDice != second.lastDice => Some(first) 
     case _ => None 
    } 
    } 
} 

// Exiting paste mode, now interpreting. 

defined class Player 
defined object Player 

scala> Player.nextPlayer(List[Player]()) 
res2: Option[Player] = None 

scala> Player.nextPlayer(List(Player(1))) 
res3: Option[Player] = Some(Player(1)) 

scala> Player.nextPlayer(List(Player(1), Player(4))) 
res5: Option[Player] = Some(Player(4)) 

scala> Player.nextPlayer(List(Player(1), Player(4), Player(4))) 
res6: Option[Player] = None 

scala> Player.nextPlayer(List(Player(1), Player(1), Player(4))) 
res7: Option[Player] = Some(Player(4)) 

注意:您必须更改顺序为降序。

+0

那么,这是更复杂的我同意,顺序必须被提取,并保持与原班谢谢!。 – Pavel

3

您可以使用maxByminBy方法:

val maxPlayer = this.players.maxBy(_.LastDice) 
val minPlayer = this.players.minBy(_.LastDice) 

否则,没有太多的优化,我认为。

+0

是的,这实际上会做。谢谢,不知道是否还有更多可以做的:def NextPlayer():Option [Player] = this.players.maxBy(_。LastDice)== this.players.minBy(_。LastDice)?无:一些(this.players.maxBy(_ LastDice) – Pavel