2017-08-27 41 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