【问题标题】:Scala: how can I sort an array of tuples by their second element?Scala:如何按第二个元素对元组数组进行排序?
【发布时间】:2011-02-07 08:19:55
【问题描述】:

Scala 中有没有一种方法可以使用任意比较函数对元组数组进行排序?特别是我需要按第二个元素对元组数组进行排序,但我想知道一种对元组数组进行排序的通用技术。

谢谢!

【问题讨论】:

    标签: arrays scala sorting tuples


    【解决方案1】:

    在 scala 2.8 中,有一个方法 sortBy。这是一个简单的用例:

    scala> val arr = Array(("One",1),("Two",2),("Four",4),("Three",3))
    arr: Array[(java.lang.String, Int)] = Array((One,1), (Two,2), (Four,4), (Three,3))
    
    scala> arr.sortBy(_._2)
    res0: Array[(java.lang.String, Int)] = Array((One,1), (Two,2), (Three,3), (Four,4))
    
    scala>
    

    【讨论】:

    • 2.8 纯属作弊。 +1
    • 很好。我必须切换到 2.8(目前使用 2.7)谢谢
    • 然而,这并没有就地排序。
    • @Daniel 是的,我刚刚写了一篇关于它的帖子:old.nabble.com/…
    【解决方案2】:

    您可以使用此代码:

    scala> val v = Array(('a', 2), ('b', 1))
    v: Array[(Char, Int)] = Array((a,2), (b,1))
    
    scala> scala.util.Sorting.stableSort(v,
         | (e1: (Char, Int), e2: (Char, Int)) => e1._2 < e2._2)
    
    scala> v
    res11: Array[(Char, Int)] = Array((b,1), (a,2))
    

    不幸的是,Scala 似乎无法推断传递给stableSort 的数组的类型。我希望你没问题。

    【讨论】:

    • 更好一点:stableSort(v, (_._2 &lt; _._2) : ((Char,Int),(Char,Int)) =&gt; Boolean) — 将关注点分开,并允许将逻辑和类型作为独立的步骤进行推理,特别是因为内联类型签名在这里只是一个麻烦。
    • 需要注意的一点是,如果您正在处理排序列中的 Any 类型(假设它有 Long),您需要执行以下操作:scala.util.Sorting.stableSort(v, (e1: (String, Any), e2: (String, Any)) => e1._2.asInstanceOf[Long]
    【解决方案3】:

    如果是Array,则通常使用就地排序算法。但是,在惯用的 Scala 代码中,通常不鼓励/使用可变集合。如果是这种情况并且您有一个不可变的集合(或者不想修改 Array),请使用 sortWith

    scala> val a = Array(1, 3, 2, 5)
    a: Array[Int] = Array(1, 3, 2, 5)
    
    scala> a.sortWith(_ > _)
    res6: Array[Int] = Array(5, 3, 2, 1)
    
    scala> a
    res7: Array[Int] = Array(1, 3, 2, 5)
    

    Array 或任何其他元组集合进行排序:

    scala> val a = Array(('a', 1), ('b', 4), ('c', 5), ('d', 2))
    a: Array[(Char, Int)] = Array((a,1), (b,4), (c,5), (d,2))
    
    scala> a.sortWith(_._2 > _._2)
    res4: Array[(Char, Int)] = Array((c,5), (b,4), (d,2), (a,1))
    
    scala> a
    res5: Array[(Char, Int)] = Array((a,1), (b,4), (c,5), (d,2))
    

    【讨论】:

    【解决方案4】:

    在 Scala 2.8 上(是的,再次:),您也可以这样做:

    val v = Array(('a', 2), ('b', 1))
    scala.util.Sorting.stableSort(v)(manifest[(Char, Int)], Ordering.by(_._2))
    

    在特定的pairs情况下,这也可以按第二个元素排序first,然后再按第一个元素:

    scala.util.Sorting.stableSort(v)(manifest[(Char, Int)], Ordering.by(_.swap))
    

    【讨论】:

      【解决方案5】:

      2.7 并没有到位:

      (Array((2,3), (4,2), (1,5)).toList.sort (_._2 < _._2)).toArray
      

      【讨论】:

        【解决方案6】:

        你可能想要来自 scala.util.Sorting 的def stableSort[K](a : Seq[K], f : (K, K) =&gt; Boolean) : Array[K]
        您的比较函数类似于_._2 &lt; _._1

        【讨论】:

          【解决方案7】:
          val l = List((2, 1), (3, 2), (0, 3))
          l sort { case(a, b) => a > b }
          

          【讨论】:

          • 问题是我有一个数组:(
          猜你喜欢
          • 2012-03-08
          • 2012-03-13
          • 2022-08-18
          • 2015-06-16
          • 2020-08-02
          • 1970-01-01
          • 2022-01-28
          • 2013-04-30
          相关资源
          最近更新 更多