2013-07-05 15 views
7

Quello che voglio fare è ordinare Elenca oggetti in scala, non ordinare gli elementi nella lista. Per esempio, se ho due liste di INT:Come posso ordinare gli oggetti [Int] in scala?

val l1 = List(1, 2, 3, 7) 
val l2 = List(1, 2, 3, 4, 10) 

che voglio essere in grado di metterli in ordine in cui l1> l2.

Ho creato una classe di casi che fa quello che mi serve ma il problema è che quando lo uso nessuno dei miei altri metodi funziona. Devo implementare tutti gli altri metodi della classe, ad esempio flatten, sortWith ecc.?

Il mio codice di classe si presenta così:

class ItemSet(itemSet: List[Int]) extends Ordered[ItemSet] { 

    val iSet: List[Int] = itemSet 

    def compare(that: ItemSet) = { 

    val thisSize = this.iSet.size 
    val thatSize = that.iSet.size 
    val hint = List(thisSize, thatSize).min 
    var result = 0 
    var loop = 0 

    val ths = this.iSet.toArray 
    val tht = that.iSet.toArray 

    while (loop < hint && result == 0) { 
     result = ths(loop).compare(tht(loop)) 
     loop += 1 
    } 
    if (loop == hint && result == 0 && thisSize != thatSize) { 
     thisSize.compare(thatSize) 
    } else 
     result 
    } 

} 

Ora, se creo un array di itemsets io possibile ordinare:

val is1 = new ItemSet(List(1, 2, 5, 8)) 
val is2 = new ItemSet(List(1, 2, 5, 6)) 
val is3 = new ItemSet(List(1, 2, 3, 7, 10)) 

Array(is1, is2, is3).sorted.foreach(i => println(i.iSet)) 

scala> List(1, 2, 3, 7, 10) 
List(1, 2, 5, 6) 
List(1, 2, 5, 8) 

I due metodi che mi stanno dando problemi sono:

def itemFrequencies(transDB: Array[ItemSet]): Map[Int, Int] = transDB.flatten.groupBy(x => x).mapValues(_.size) 

l'errore che ottengo è:

Espressione di tipo Map [Niente, Int] non è conforme al tipo di mappa previsto [Int, Int]

e per questo uno:

def sortListAscFreq(transDB: Array[ItemSet], itemFreq: Map[Int, Int]): Array[List[Int]] = { 
    for (l <- transDB) yield 
    l.sortWith(itemFreq(_) < itemFreq(_)) 
} 

ottengo:

non può risolvere il simbolo sortWith.

Esiste un modo per estendere List [Int] in modo da poter ordinare una raccolta di elenchi senza perdere la funzionalità di altri metodi?

risposta

14

La libreria standard fornisce a lexicographic ordering per le raccolte di oggetti ordinati. Si può mettere in campo di applicazione e il gioco è fatto:

scala> import scala.math.Ordering.Implicits._ 
import scala.math.Ordering.Implicits._ 

scala> val is1 = List(1, 2, 5, 8) 
is1: List[Int] = List(1, 2, 5, 8) 

scala> val is2 = List(1, 2, 5, 6) 
is2: List[Int] = List(1, 2, 5, 6) 

scala> val is3 = List(1, 2, 3, 7, 10) 
is3: List[Int] = List(1, 2, 3, 7, 10) 

scala> Array(is1, is2, is3).sorted foreach println 
List(1, 2, 3, 7, 10) 
List(1, 2, 5, 6) 
List(1, 2, 5, 8) 

Il Ordering type class è spesso più conveniente che Ordered a Scala-it permette di specificare come un certo tipo esistente dovrebbe essere ordinato senza dover cambiare il suo codice o creare una classe proxy che si estende Ordered[Whatever], che come hai visto può diventare disordinato molto rapidamente.

+0

Grazie mille! Non posso credere di aver appena trascorso 2 giorni cercando di far funzionare tutto. –

+0

@Val, immagino che sia sarcasmo ma ti manca il punto: la _array_ delle liste non è ordinata prima di chiamare '.sorted', e poi lo è. Inoltre sto solo usando gli esempi dell'OP, che è generalmente una buona idea. –

Problemi correlati