2009-09-23 13 views
23

mam groovy wykaz wykazów tjGroovy list.sort przez pierwszych, drugich elementów następnie trzecich

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

Chcę sortować według kolejności pierwszego elementu, potem drugi, potem trzeci.

Oczekiwany

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

Zacząłem list = list.sort{ a,b -> a[0] <=> b[0] } ale tylko sortuje pierwszy element. Jak kończysz?

Dzięki

+0

Sprawdź ten post http://stackoverflow.com/questions/4882992/grails-mapping-sort-on-multiple-fields- groovy-sort-on-multiple-map-entries – LukeSolar

Odpowiedz

22

Powinieneś być w stanie wykonać iterację pożądany sortowanie w odwrotnej kolejności:

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

Każda powinna zastąpić poprzednią tylko na tyle, aby sortowanie połączone było nienaruszone.


Można również łańcucha je w kolejności z Elvis operator, ?:, który będzie odroczyć do następnego porównania, gdy poprzednia są równe (a <=> powraca 0):

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

To wydaje się działać dobrze. –

+4

Powinien - teoretycznie - być może - dlaczego go nie sprawdziłeś? Prawidłowa odpowiedź jest ostatnia i możesz pozbyć się nawiasów: 'list.sort {a, b -> a [0] <=> b [0]?: A [1] <=> b [1]?: A [ 2] <=> b [2]} ' – Tobia

0

Oto co wymyśliłem, nie najbardziej porywające sposób przypuszczam ..

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

Jeśli chcesz sortować tablice arbitralnej (chociaż jednorodna) długości, można korzystać z tej i będzie to zrobić w jednym przebiegu:

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

można użyć Kobo-commons' Biblioteka CollectionUtils.

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

Można to zrobić w jednym wierszu:

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

Sporządzono Groovy sposób, niezależnie od wielkości podlist:

ll.sort { l1, l2 -> 
    (e1, e2) = [l1, l2].transpose().find { e1, e2 -> 
     e1 != e2 
    } 
    e1 <=> e2 
} 
Powiązane problemy