Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define Ordering[Array[Byte]]?

Tags:

scala

Is it necessary to provide the implementation from scratch? I could not find any matching implicit, not even in last-resort Implicits trait. seqDerivedOrdering obviously doesn't work, since Array is not a Seq.

like image 659
venechka Avatar asked Aug 18 '11 15:08

venechka


2 Answers

If you want it to be efficient, you'll have to write your own (this one handles nulls; if you can assume no nulls, just use the long else block):

val o = new math.Ordering[Array[Byte]] {
  def compare(a: Array[Byte], b: Array[Byte]): Int = {
    if (a eq null) {
      if (b eq null) 0
      else -1
    }
    else if (b eq null) 1
    else {
      val L = math.min(a.length, b.length)
      var i = 0
      while (i < L) {
        if (a(i) < b(i)) return -1
        else if (b(i) < a(i)) return 1
        i += 1
      }
      if (L < b.length) -1
      else if (L < a.length) 1
      else 0
    }
  }
}

Otherwise, you can .toSeq to package into a WrappedArray and defer to a Seq compare instead of doing your own scan. (This will end up boxing and unboxing your bytes, which is why it's not efficient. Since byte boxing is generally done by lookup in a table of all bytes, it's not horribly inefficent, so you may be able to get away with it unless you're doing e.g. heavy duty binary file processing.)

like image 162
Rex Kerr Avatar answered Sep 20 '22 14:09

Rex Kerr


If you're into brevity rather than raw performance:

scala> Ordering.by((_: Array[Byte]).toIterable)
res0: scala.math.Ordering[Array[Byte]] = scala.math.Ordering$$anon$7@8c9f531
like image 34
retronym Avatar answered Sep 18 '22 14:09

retronym