1

Let's consider the following Array[Array[Int]

val array = Array(Array(7,3,2,1), Array(3,2,5,1), Array(2,1,4,6), Array(1,2,3,4))

I would like to have this result

val sortedArray = Array(Array(1,2,3,4), Array(1,2,3,5), Array(1,2,3,7), Array(1,2,4,6))

If we know that each inner array have the same size n we start to sort each inner array then use sortBy

val sortedArray = array.map(_.sorted).sortBy(x => (x(0), x(1), x(2), x(3)))

Unfortunately if we don't know the inner array size in advance or if it's huge we cannot proceed as seen above. Maybe it is possible to define a custom ordering in a dynamic way..

In this case i can also do

val sortedArray = array.map(_.sorted).map(a => (a.reduce(_+_), a)).sortBy(_._1).map(_._2)

But it works because elements in each array are present a uniq time for each array.

4
  • Doesn't doing only array.map(_.sorted) get you the results you want ? Commented May 14, 2017 at 8:47
  • No because i want to sort the result of array.map(_sorted) to have them ordered Commented May 14, 2017 at 8:50
  • @KyBe In your desired sortedArray result, shouldn't Array(1,2,3,7) come before Array(1,2,4,6)? Commented May 14, 2017 at 12:02
  • Little mistake of mine Commented May 14, 2017 at 12:03

1 Answer 1

3

You can implement your own Ordering for the array elements like:

val array = Array(Array(7,3,2,1), Array(3,2,5,1), Array(2,1,4,6), Array(1,2,3,4))

implicit object IntArrayOrdering extends Ordering[Array[Int]] {
  override def compare(x: Array[Int], y: Array[Int]): Int =
    compareStream(x.toStream, y.toStream)

  private def compareStream(x: Stream[Int], y: Stream[Int]): Int = {
    (x.headOption, y.headOption) match {
      case (Some(xh), Some(yh))  => 
        if (xh == yh) {
          compareStream(x.tail, y.tail)
        } else {
          xh.compare(yh)
        }
      case (Some(_), None) => 1
      case (None, Some(_)) => -1
      case (None, None) => 0
    }
  }
}

array.map(_.sorted).sorted
Sign up to request clarification or add additional context in comments.

2 Comments

But note that this particular implementation is going to perform badly, as tail on arrays has to create a new array and copy elements there, unlike Lists.
True. A simple way to improve performance, as I did in the updated answer above, is to turn Array[Int] into Stream[Int] before the recursion. Of course, you might squeeze even more speed by going lower level and access the Array[Int] directly by index.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.