Reputation: 13
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
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
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