2009-09-23 8 views
23

Ich habe eine Liste von Listen groovy d.h.Groovy List.Sort von ersten, zweiten, dann dritten Elementen

list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]] 

I es Art im Auftrag des ersten Elements möchte, dann die zweite, dann dritten.

Erwartet

assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]] 

Ich begann mit list = list.sort{ a,b -> a[0] <=> b[0] } aber, dass sortiert nur das erste Element. Wie beendest du?

Dank

+0

prüfen Diesen Beitrag http://stackoverflow.com/questions/4882992/grails-mapping-sort-on-multiple-fields- groovy-sort-on-multiple-map-Einträge – LukeSolar

Antwort

22

Sie können die zu durchlaufen in umgekehrter Reihenfolge Sortierung gewünscht:

list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]] 

list = list.sort{ a,b -> a[2] <=> b[2] } 
list = list.sort{ a,b -> a[1] <=> b[1] } 
list = list.sort{ a,b -> a[0] <=> b[0] } 

assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]] 

Jeder sollte die vorherige gerade genug überschreiben, um die kombinierte Sortierung intakt zu halten.


Sie können auch verketten sie, um mit dem Elvis operator, ?:, die auf den nächsten Vergleich verschieben wird, wenn die vorherige gleich sind (und <=> kehrt 0):

list.sort { a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2] } 
+0

Das scheint gut zu funktionieren. –

+4

Es sollte - in der Theorie - potenziell - warum haben Sie es nicht einfach überprüft? Die richtige Antwort ist die letzte und Sie können die Klammern weglassen: 'list.sort {a, b -> a [0] <=> b [0]?: A [1] <=> b [1]?: A [ 2] <=> b [2]} ' – Tobia

0

Hier ist, was ich mit, nicht die groovy Art und Weise

Ich nehme an sollte kam ..
list = list.sort{ a,b -> 
    if(a[0].compareTo(b[0]) == 0) { 
     if(a[1].compareTo(b[1]) == 0) { 
      return a[2].compareTo(b[2]); 
     } else { 
      return a[1].compareTo(b[1]); 
     } 
    } else { 
     return a[0].compareTo(b[0]); 
    } 
} 
7

Wenn Sie Arrays sortieren willkürlicher (obwohl homogen) Länge, können Sie diese verwenden, und es wird es in einem einzigen Durchgang tun:

def list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]] 

list.sort { a, b -> 
    for (int i : (0..<a.size())) { 
     def comparison = (a[i] <=> b[i]) 
     if (comparison) return comparison 
    } 
    return 0 
} 

assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]] 
4

können Sie kobo-commons nutzen CollectionUtils-Bibliothek.

http://wiki.github.com/kobo/kobo-commons/sort-by-multiple-keys

import org.jggug.kobo.commons.lang.CollectionUtils 

CollectionUtils.extendMetaClass() 


list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]] 
list = list.sort{ [ it[0], it[1], it[2] ]} // sort by multiple keys 
assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]] 

list2 = [ [name:"a", age:13], [name:"a",age:15], [name:"b", age:13] ] 
list2 = list2.sort{[it.name, it.age] } // sort by name and age 
assert list2 == [[name:"a", age:13], [name:"a", age:15], [name:"b", age:13]] 
0

Sie können es in einer Zeile tun:

list.sort { String.format('%010d%010d%010d', it[0], it[1], it[2]) } 
1

die Groovy Art und Weise getan, und zwar unabhängig von der Größe der Teillisten:

ll.sort { l1, l2 -> 
    (e1, e2) = [l1, l2].transpose().find { e1, e2 -> 
     e1 != e2 
    } 
    e1 <=> e2 
} 
Verwandte Themen