【问题标题】:Scala: How can I explicitly compare two Options?Scala:如何明确比较两个选项?
【发布时间】:2014-06-10 14:58:03
【问题描述】:

如果我有两个选项,例如

val a = Option(2)
val b = Option(1)

我会写

List(a,b).sorted

并通过插入隐式排序正确排序。我怎样才能获得对这个 Ordering 的引用,以便我可以调用 compare(a,b) 并获得结果?我想要相当于

val comparison = a.compare(b)

除了没有 a 和 b 是 Ordered 的实例。

【问题讨论】:

    标签: scala option implicit


    【解决方案1】:

    您可以直接要求隐式排序:

    Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_21).
    Type in expressions to have them evaluated.
    Type :help for more information.
    
    scala> implicitly[Ordering[Option[Int]]]
    res0: Ordering[Option[Int]] = scala.math.Ordering$$anon$3@501a9177
    
    scala> res0.compare(Some(1), Some(3))
    res1: Int = -1
    

    【讨论】:

    • 有效,但无需要求隐式排序。 Ordering[Option[Int]].compare(a, b) 也可以。
    【解决方案2】:

    操作选项的最佳方法是使用for 表达式。

    for (a1 <- a; b1 <- b) yield a1.compare(b1)  // Some(-1)
    

    如果至少有一个数字是None,则结果是None

    val x: Option[Int] = None
    for (a1 <- a; b1 <- x) yield a1.compare(b1)  // None
    

    比较函数可以定义为

    def compare(a: Option[Int], b: Option[Int]) = {
      for (a1 <- a; b1 <- b) yield a1.compare(b1)
    }.get
    

    更新:

    如果你想要 Nones,你可以使用模式匹配:

    def compare(a: Option[Int], b: Option[Int]) = (a, b) match {
      case (Some(a), Some(b)) => a.compare(b)
      case (None, None)       => 0
      case (None, _)          => -1  // None comes before
      case (_, None)          => 1
    }
    
    val list: List[Option[Int]] = List(List(Some(1), None, Some(4), Some(2), None))
    val list2 = list.sortWith(compare(_, _) < 0)    
    //  list2 = List(None, None, Some(1), Some(2), Some(4))
    

    【讨论】:

    • 这是一个有趣的成语。对于我的用例,我实际上也希望首先或最后订购无,所以我不能在这里使用它,但它在其他情况下看起来很方便。
    • 小心!如果 a 或 b(或两者)为 None,则第一个比较函数示例将引发 NoSuchElementException。
    猜你喜欢
    • 2011-07-20
    • 2021-04-26
    • 1970-01-01
    • 2012-03-03
    • 2014-12-05
    • 2018-12-08
    • 1970-01-01
    • 2018-10-09
    • 2016-08-24
    相关资源
    最近更新 更多