tokyo
tokyo

Reputation: 13

Is this the correct way to sort generic type?

I am just trying to write a bubble sorting code using generic. I am not sure whether this is the right approach to writing sorting logic for generic. Here "if" condition is giving compile time error. For any particular type, this is working fine. How can I resolve this and program it in a better way? Thanks in advance.

def sortAny[T](list: Array[T]): Array[T] = {
var count = 0
while (count < list.length) {
  for (count <- 0 until list.length - 1) {
    if (list(count) > list(count + 1)) {
      val temp = list(count)
      list(count) = list(count + 1)
      list(count + 1) = temp
    }
  }
  count = count + 1
}

list

}

Upvotes: 1

Views: 251

Answers (2)

Alin Gabriel Arhip
Alin Gabriel Arhip

Reputation: 2638

Adding a context bound answer for completeness. To use it, one requires a type class instead of a type conversion, that has a comparison method which takes 2 elements of type T.

A type class here means a module that implements a set of functions. This is a common pattern of Ad-Hoc Polymorphism in functional languages like Haskell, which have influenced Scala to adopt it.

The Ordered trait is unsuitable as a type class here, because it's comparison method takes only 1 element of type T. Ordered is meant to be mixed in and compare the this instance with the element T provided. The solution is of course to use the Ordering trait instead:

  def sortAny[T: Ordering](list: Array[T]): Array[T] = {
    var count = 0
    while (count < list.length) {
      for (count <- 0 until list.length - 1) {
        if (implicitly[Ordering[T]].gt(list(count), list(count + 1))) {
          val temp = list(count)
          list(count) = list(count + 1)
          list(count + 1) = temp
        }
      }
      count = count + 1
    }

    list
  }

This works both for built-in types, because Scala provides implicit orderings for them:

  sortAny(Array(4, 2, 5, 7, 32, 1213, 32))            // Array(2, 4, 5, 7, 32, 32, 1213)
  sortAny(Array("John", "Helen", "Merry", "Chris"))   // Array(Chris, Helen, John, Merry)

And for custom types too, but you'll have to either provide an implicit Ordering - or - mix in the Ordered trait in your custom type. The latter works because:

Ordered and Ordering both provide implicits allowing them to be used interchangeably.

Scala will automatically create an implicit Ordering for your custom type, as long as it mixes in Ordered.

Upvotes: 1

ADK
ADK

Reputation: 33

def sortAny[T <% Ordered[T]](list: Array[T]): Array[T] = {
var count = 0
while (count < list.length) {
  for (count <- 0 until list.length - 1) {
    if (list(count) > list(count + 1)) {
      val temp = list(count)
      list(count) = list(count + 1)
      list(count + 1) = temp
    }
  }
  count = count + 1
  }

list
}

Output will be

sortAny: [T](list: Array[T])(implicit evidence$1: T => Ordered[T])Array[T]

T <% S (a view bound) says that type T must be convertible to S, so it has to be either a subtype of S or have implicit conversion defined.

Upvotes: 0

Related Questions