views:

522

answers:

6

Hi all,

is there a way in Scala to sort an array of tuples using and arbitrary comparison function? In particular I need to sort and array of tuples by their second element, but I wanted to know a general technique to sort arrays of tuples.

Thanks!

+5  A: 

You can use this code:

scala> val v = Array(('a', 2), ('b', 1))
v: Array[(Char, Int)] = Array((a,2), (b,1))

scala> scala.util.Sorting.stableSort(v,
     | (e1: Tuple2[Char, Int], e2: Tuple2[Char, Int]) => e1._2 < e2._2)

scala> v
res11: Array[(Char, Int)] = Array((b,1), (a,2))

Unfortunetly, it seems that Scala cannot infer the type of the array passed to stableSort. I hope that's ok for you.

Michel Krämer
That's what I was looking for! Thanks a lot!
pau.estalella
+1  A: 

You probably want def stableSort[K](a : Seq[K], f : (K, K) => Boolean) : Array[K] from scala.util.Sorting.
Your comparison function would be something like _._2 < _._1

tstenner
+13  A: 

In scala 2.8, there is a method sortBy. Here is a simple use case:

Welcome to Scala version 2.8.0.r21376-b20100408020204 (Java HotSpot(TM) Client VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.

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>
Eastsun
Learned about the sortBy from you answer, thanks !
Jawher
2.8 is just plain cheating. +1
tstenner
Gooood. I'll have to switch to 2.8 (currently using 2.7) Thanks
pau.estalella
This does not sort in place, however.
Daniel
@Daniel Yes, and I just wrote a post about it: http://old.nabble.com/Is-it-possible-to-use-filter-or-sort-method-of-a-mutable-Seq-without-creating-new-Seq--td28222943.html
Eastsun
A: 
val l = List((2, 1), (3, 2), (0, 3))
l sort { case(a, b) => a > b }
Jawher
Problem is I have an Array :(
pau.estalella
A: 

On Scala 2.8 (yes, again :), you can also do this:

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

In the specific case of pairs, this can also work to sort first by the second element, and then by the first:

scala.util.Sorting.stableSort(v)(manifest[(Char, Int)], Ordering.by(_.swap))
Daniel
+1  A: 

2.7 and not in place:

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