2016-05-16 23 views
65

Załóżmy, że mam listę osób, które muszę sortować według wieku, a następnie według nazwy.Sortowanie kolekcji według wielu pól w Kotlin

Pochodzę z C# -background, mogę łatwo osiągnąć to we wspomnianej język za pomocą LINQ:

var list=new List<Person>(); 
list.Add(new Person(25, "Tom")); 
list.Add(new Person(25, "Dave")); 
list.Add(new Person(20, "Kate")); 
list.Add(new Person(20, "Alice")); 

//will produce: Alice, Kate, Dave, Tom 
var sortedList=list.OrderBy(person => person.Age).ThenBy(person => person.Name).ToList(); 

jaki sposób można tego dokonać przy użyciu Kotlin?

To, co starałem (to oczywiście błędne, ponieważ wyjście z pierwszego „sortedBy” klauzula zostanie zastąpiona przez drugi co przekłada się na liście sortowane według nazwy tylko)

val sortedList = ArrayList(list.sortedBy { it.age }.sortedBy { it.name })) //wrong 

Odpowiedz

110

sortedWith + compareBy (biorąc vararg z lambdas) rade:

val sortedList = list.sortedWith(compareBy({ it.age }, { it.name })) 

można również użyć nieco bardziej zwięzły wpłacone składni odniesienie:

val sortedList = list.sortedWith(compareBy(Person::age, Person::name)) 
+1

Kotlin jest darem niebios – ElliotM

38

Użyj sortedWith, aby posortować listę przy pomocy Comparator.

Następnie można skonstruować porównawczy stosując kilka sposobów:

  • compareBy, thenBy skonstruować porównawczy w łańcuchu połączeń:

    list.sortedWith(compareBy<Person> { it.age }.thenBy { it.name }.thenBy { it.address }) 
    
  • compareBy ma przeciążenia, który trwa kilka funkcji:

    list.sortedWith(compareBy({ it.age }, { it.name }, { it.address })) 
    
+0

Dzięki, tego właśnie szukałem! Jestem trochę nowy w kotlinach, dlaczego musisz mieć 'compareBy ' w przeciwieństwie do 'compareBy' w swoim pierwszym punkcie wypunktowania? – Aneem

+0

@Aneem, kompilator Kotlin czasami nie może wywnioskować argumentu typu, który należy podać ręcznie. Jednym z takich przypadków jest oczekiwany typ ogólny i chcemy przekazać wynik łańcucha wywołań funkcji ogólnych, np. 'CompareBy {it.age} .thenBy {it.name} .thenBy {it.address}'. W drugim punkcie istnieje tylko jedno wywołanie funkcji, bez połączeń łańcuchowych: 'compareBy ({it.age}, {it.name}, {it.address})'. – hotkey

Powiązane problemy