【问题标题】:Sorting by a partial order in Scala在Scala中按偏序排序
【发布时间】:2017-03-18 07:24:06
【问题描述】:

Partially sorting collections in Scala 询问如何在 Scala 中按 PartialOrdering 排序。评论指出作者不应该在给出的示例中进行部分排序。我确实需要按偏序排序——我的国家可能是其他国家的飞地,这会导致偏序。

那么:给定一个List[T],其中T 扩展PartialOrdering[T],有没有一种根据偏序排序的合理方法?

【问题讨论】:

标签: scala sorting partial-ordering


【解决方案1】:

我自己写了一个合适的排序。像这样的案例总是让我觉得我错过了一个标准库函数。

  def sortByPartialOrdering[T](ts: Array[T], lessThan: (T, T) => Boolean): ListBuffer[T] = {
    val len = ts.size
    val visited = Array.fill[Boolean](len)(false)
    val postOrder = ListBuffer.empty[Int]

    def visit(n: Int): Unit = {
      visited(n) = true
      for (i <- 0 until len)
        if (!visited(i) && lessThan(ts(i), ts(n)))
          visit(i)
      postOrder += n
    }

    for (i <- 0 until len)
      if (!visited(i))
        visit(i)

    assert(postOrder.size == len)

    postOrder map ts
  }

欢迎评论/改进——我不会写那么多 Scala。

【讨论】:

    【解决方案2】:

    我不完全确定我理解这个问题。但也许这种从PartialOrderingOrdering 的转换有效:

    def sortWithPartialSort[A : PartialOrdering](list: Seq[A]): Seq[A] = {
      list.sorted(
        Ordering.fromLessThan { case (x,y) =>
          implicitly[PartialOrdering[A]].lt(x, y)
        }
      )
    }
    

    注意PartialOrdering.lt定义为:

    def lt(x: T, y: T): Boolean = lteq(x, y) && !equiv(x, y)
    def equiv(x: T, y: T): Boolean = lteq(x,y) && lteq(y,x)
    

    所以如果我理解正确的话,只需 lteq 你就可以定义一个完整的排序。

    另请注意,Seq.sorted 实现了稳定的排序,因此相同的项目不会重新排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-30
      • 2011-01-31
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多