3

I want to extend a sort method for scala Array which can return the original indecies.

The code I writed below:

object ArrayExtend {
implicit class ArrayExtension(val array: Array[Int]) {
    def argSort(): Array[Int] = {
                var tupleArray = for (i <- 0 until array.length) yield (i, array(i))     

                    tupleArray = tupleArray.sortWith((x,y)=> x._2 < y._2)

                    val result = for((index,_) <- tupleArray) yield index

                    return result.toArray

    }
}


def main(args:Array[String]){
val array = Array(5,4,3,2,0)
for(i <- array.argSort()) print(i)
}

}

This code works on Array[Int], how can I extend this method to all different types of Array? I didn't find any compare method in the AnyRef class.

2 Answers 2

8

It's enough if you require that type T can be implicitly converter into Ordered[T]. Normally it would be done by adding implicit converter to the class or method parameters with (implicit converter: T => Ordered[T]), however scala provides view bounds <% exactly for such cases. From the book: You can think of "T <% Ordered[T]" as saying. " I can use any T, as long as T can be treated as an Ordered[T]."

So the code would look like this:

implicit class ArrayExtension[T <% Ordered[T]](val array: Array[T]) {
  def argSort = array.zipWithIndex.sortBy(_._1).map(_._2).toArray
}

val array = Array(5,4,3,2,0)
val array2 = Array(5f,4f,3f,2f,0f)

array.argSort foreach print //43210
println
array2.argSort foreach print //43210
Sign up to request clarification or add additional context in comments.

Comments

0

You can do this by using an implicit conversion to Ordered. You also need to parametrize your type. Change the code to the following:

implicit class ArrayExtension[T](val array: Array[T])(implicit view: (T) => Ordered[T]) {
  def argSort(): Array[Int] = {
    var tupleArray = for (i <- 0 until array.length) yield (i, array(i))
    tupleArray = tupleArray.sortWith((x, y) => x._2 < y._2)
    val result = for ((index, _) <- tupleArray) yield index
    result.toArray
 }

}

Ordered is

A trait for data that have a single, natural ordering.

and

Classes that implement this trait can be sorted with scala.util.Sorting and can be compared with standard comparison operators (e.g. > and <).

So any class that implements Ordered trait (directly or via an implicit conversion) can be used with sorting methods. You can implement this trait for your own data types in order to make them sortable.

Comments

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.