2017-08-27 40 views
0

我有一個案例類節點,我已經寫了,並從中創建一個列表,我需要找到具有最大磁盤的節點。 我寫了下面的代碼,有沒有更好的方法呢?另外,在我的實際生產代碼中,我的「nodeList」變量將不只是Option[List[Node]]而且Future[Option[List[Node]]]。我猜想答案/代碼不會改變太多,除非我會做一個map/flatMap去面向未來並且做同樣的事情。 如果有人有更好的建議寫下面的代碼更多斯卡拉的方式,請分享你的想法。從案例類獲取最大值節點列表,返回Scala選項[列表]

scala> case class Node(disk: Integer, name: String) 

定義的類節點

scala> val nodeList = Option(List(Node(40, "node1"), Node(200, "node3"),Node(60, "node2"))) 
nodeList: Option[List[Node]] = Some(List(Node(40,node1), Node(200,node3), Node(60,node2))) 

scala> val maxDisk = nodeList match { 
| case None => println("List is empty"); None 
| case Some(lst) => { 
| Some(lst.max(Ordering.by((_:Node).disk))) 
| } 
| }` 
maxDisk: Option[Node] = Some(Node(200,node3)) 

回答

1

由你寫的代碼來看,我不知道,如果你真的應該使用Optional[List[Node]]。您似乎將None視爲空的List,並且您不檢查Some情況下的空白列表。你可能想看看是否只是一個簡單的List[Node]更適合你的使用(其中None將變爲Nil,而Some(lst)只是lst,並且未使用的Some(Nil)情況不再存在以混淆任何人)。

如果你保持Optional[List[Node]],我會做這樣的:

nodeList 
    .filterNot(_.isEmpty) // maxBy throws if the list is empty; check for it 
    .map(_.maxBy(_.disk)) // maxBy looks nicer than max(Ordering.by) 

如果切換到List[Node],這是稍微難看:

Some(nodeList) 
    .filterNot(_.isEmpty) // We're using the filter utility of Option here, 
    .map(_.maxBy(_.disk)) // so I wrap with Some to get access to filterNot. 
+0

謝謝。我有2個問題。 1.如果我正在使用Option [List],那麼您的答案是否被認爲是更好的做法?這不是爲了挑戰你的答案,而是爲了瞭解我的解決方案是否功能較差或較不理想,以及爲什麼。對於我自己的學習只有 2.您提出的第二種方法,比使用選項類型I a好嗎? 3.如果列表爲空,我的sol會打破? – curiousengineer

+0

1:我建議不要使用'Option [List]'只是因爲你沒有使用它。如果你需要告訴'None'除了'Some(Nil)'以外,那麼一定要用它。您應該儘量避免使用「太大」的數據類型供您使用(它們具有您不使用的值)。 2:我的第二個解決方案只是告訴你,如果你切換到List [Node],代碼將會是什麼樣子。這不是更好或更糟;不同之處在於你對'Option [List]'和'List'的回答。 3:是的,如果你有'Some(Nil)',你的原始解決方案將會中斷。 – HTNW

1

您可以使用遞歸以列表模式匹配。

case class Node(disk: Integer, name: String) 
    val nodeList = Option(List(Node(40, "node1"), Node(200, "node3"),Node(60, "node2"))) 

    def findMaxValue(list: List[Node]): Option[Node] = list match { 
    case Nil => None 
    case List(x) => Some(x) 
    case first :: second :: rest => if(first.disk > second.disk) findMaxValue(first::rest) else findMaxValue(second::rest) 
    } 

    val node:Option[Node] = findMaxValue(nodeList.getOrElse(Nil)) 
    println(node.get.disk) //print 200