2016-03-07 24 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