【问题标题】:more elegant way to write if( list.nonEmpty) Some(list.max) else None?更优雅的写法 if(list.nonEmpty) Some(list.max) else None?
【发布时间】:2013-12-27 05:49:48
【问题描述】:

List.max 基于某种排序返回列表的“最大”元素...但是如果列表为空,您将收到 java.lang.UnsupportedOperationException: empty.max 异常。我真的不喜欢用 if 语句或匹配或其他东西乱扔代码。我想要 headOption 之类的 max,但我没有看到这样的方法。获得list.maxOption 等价物的最优雅方式是什么?

【问题讨论】:

  • 那不是将 if 子句移到其他地方吗?
  • 把实现放到一个类型类里面?

标签: scala functional-programming max scala-option


【解决方案1】:

您可以将 Try 转换为 Option:

Try(empty.max).toOption

您也可以使用 reduceOption(如scala - Min/max with Option[T] for possibly empty Seq? 中给出的):

l.reduceOption(_ max _)

【讨论】:

  • 虽然这个选项非常优雅,但就性能而言,if 比打开try 块要便宜得多,并且可能会产生堆栈跟踪异常。如果您关心性能,请选择其他选项之一。
  • 我喜欢所有这些答案,但选择这个是为了获得更多想法的链接。
【解决方案2】:

或者自己写:

implicit class WithMaxOption[T: Ordering](self: Seq[T]) {
  def maxOption() = if(self.isEmpty) None else Some(self.max)
}

List(1,2,3).maxOption  // Some(3)
List[Int]().maxOption  // None

【讨论】:

  • 为了我自己的教育:这里有理由使用Seq[T]而不是Traversable[T]吗?
  • @Rob,没有理由。更一般的就好了。
  • 我认为这是最好的答案,pre-2.13。
【解决方案3】:

Scala 2.13 开始,minOption/maxOption 现在是标准库的一部分:

List(34, 11, 98, 56, 43).maxOption // Option[Int] = Some(98)
List[Int]().maxOption              // Option[Int] = None

【讨论】:

    【解决方案4】:

    这是实现它的一种方法:

    Some(list).filter(_.nonEmpty).map(_.max)
    

    【讨论】:

      【解决方案5】:

      另一种表述是

      list.headOption.map(_ => list.max)
      

      【讨论】:

      • 我倾向于同意!要记住的是,map/filter 方法中的函数不必使用传递给它的参数
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-25
      • 2012-06-07
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多