2011-08-18 14 views
6

È necessario fornire l'implementazione da zero? Non sono riuscito a trovare alcun riscontro implicito, nemmeno nel tratto Impliciti dell'ultimo resort. seqDerivedOrdering ovviamente non funziona, poiché Array non è un Seq.Come definire l'ordinamento [Array [Byte]]?

risposta

2

È possibile implementare un semplicissimo Ordering che chiama toSeq su array con comapred e chiama quindi lo seqDerivedOrdering. La conversione in Seq dovrebbe essere quasi gratuita in termini di prestazioni.

8

Se si vuole che sia efficace, dovrete scrivere il proprio (questo uno gestisce valori nulli, se si può supporre non nulli, basta utilizzare il lungo blocco 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 
    } 
    } 
} 

In caso contrario, puoi .toSeq impacchettare in un WrappedArray e rimandare a un confronto Seq invece di fare la tua scansione. (Questo finirà per inscatolare e unboxing dei tuoi byte, motivo per cui non è efficiente. Dal momento che il boxing di byte viene generalmente eseguito cercando in una tabella di tutti i byte, non è orribilmente inefficente, quindi potresti riuscire a farla franca a meno che non si sta facendo ad esempio l'elaborazione di file binario pesanti)

+0

Sì, ho voluto aggiungere qualcosa di simile, ma volevo chiedere prima. Forse ha senso aggiungere qualcosa a stdlib per renderlo più ovvio? – venechka

+0

@venechka - Sarebbe bello se l'oggetto 'Array' li implementasse per ogni tipo. Forse qualcuno dovrebbe presentare una richiesta di miglioramento? Nel frattempo, però, ci sono _lots_ di cose pratiche che la libreria standard non ha. Dovresti abituarti ad avere la tua libreria standard personale per riempire quei pezzi che ti servono! –

+0

è sufficiente avere una singola versione spececizzata, penso. – venechka

7

Se siete in brevità piuttosto che le prestazioni grezzo:.

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