I have this segment of Scala code which defines an ordering and applies it to a TreeSet. This part compiles fine.
val acctOrdering = new Ordering[Account] {
def compare(acc1: Account, acc2: Account) {
// code to compare based on various criteria
}
}
private var accountSet = new TreeSet[Account]()(acctOrdering)
Elsewhere in the code, I want to get the first element in the set (and later on get subsequent ones if the first one doesn't produce what I want, although that usually won't be necessary), based on the order I previously specified. I thought the following would work, but it didn't compile:
val firstAccount = accountSet.min
The error is "could not find implicit value for parameter cmp: Ordering[Account]"
However, if I specify the ordering object again when asking for the minimum, it compiles:
val firstAccount = accountSet.min(acctOrdering)
I thought it would have automatically used the ordering I gave at construction time, and incrementally sorting as I added to the set, so I wouldn't have to specify the ordering again when calling min
.
What am I doing wrong? Do I need to explicitly define an implicit function somewhere?
What is happening is that you are assuming min
depends on the ordering of the set, but it doesn't. Specifically, min
and max
are generic methods available on pretty much any collection, and they take an implicit Ordering
parameter.
However, if you try firstKey
and lastKey
, which are SortedSet
-specific methods, they'll work without having to pass any implicit.
Edit
One question you might have posed is to how do you make sure your Account
type can be ordered by any method expecting an Ordering
. You can do that by putting an implicit definition inside Account
's object companion, like this:
object Account {
implicit val ord = new Ordering[Account] {
def compare(ac1: Account, acc2: Account): Int = {
// code to compare based on various criteria
}
}
}
Once you do that, you won't need to pass the ordering explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With