2011-08-18 56 views

回答

2

您可以實現一個非常簡單的Ordering,它在共映射陣列上調用toSeq,然後調用seqDerivedOrdering。就性能而言,轉換爲Seq應該幾乎是免費的。

8

如果你希望它是有效的,你必須編寫自己的(這個處理空值;如果你可以假設沒有空,只使用長else塊):

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 
    } 
    } 
} 

否則,您可以將.toSeq打包到WrappedArray,並推遲到Seq比較,而不是進行自己的掃描。 (這會結束裝箱和解開你的字節,這就是爲什麼它效率不高的原因。由於字節裝箱通常是通過在所有字節的表格中查找來完成的,所以它不是很糟糕,所以你可能能夠避開它除非你做如重型二進制文件處理)

+0

是的,我想添加這樣的事情,但要問了。也許有必要添加一些東西到stdlib,使其更明顯? – venechka

+0

@venechka - 如果'Array'對象爲每種類型實現了這些將會很好。也許有人應該提交增強請求?但與此同時,標準庫沒有一些便利的東西。你應該習慣於擁有你自己的個人標準庫來填寫你需要的部分! –

+0

這足以讓我想到一個@specialized版本。 – venechka

7

如果你到簡潔,而不是原始性能:

scala> Ordering.by((_: Array[Byte]).toIterable) 
res0: scala.math.Ordering[Array[Byte]] = [email protected]