Kotlin - Idiomatyczny sposób na usunięcie zduplikowanych ciągów z tablicy?

110

Jak usunąć duplikaty z Array<String?>kotlina?

jturolla
źródło
Jeśli ktoś szuka kolejnych postaci do usunięcia, odwiedź stronę handyopinion.com/…
Asad Ali Choudhry

Odpowiedzi:

210

Użyj distinctfunkcji rozszerzenia :

val a = arrayOf("a", "a", "b", "c", "c")
val b = a.distinct() // ["a", "b", "c"]

Istnieje również distinctByfunkcja, która pozwala określić, jak rozróżnić elementy:

val a = listOf("a", "b", "ab", "ba", "abc")
val b = a.distinctBy { it.length } // ["a", "ab", "abc"]

Jak @ mfulton26 zasugerował, można również używać toSet, toMutableSeta jeśli nie trzeba oryginalną kolejność być zachowane, toHashSet. Te funkcje tworzą Setzamiast a Listi powinny być nieco bardziej wydajne niż distinct.


Może ci się przydać:

Klawisz skrótu
źródło
5
Możesz także użyć toSetlub toMutableSetktóre mają mniejszy narzut niż, distincta jeśli zamówienie nie ma znaczenia, możesz użyć toHashSet.
mfulton 26
@ mfulton26, z pewnością nie zawsze ma to narzut. Np. Obiekt encji JPA może mieć leniwie ładowane pola, więc bardziej wydajne jest odróżnienie jego kolekcji według identyfikatora niż wykonanie pełnego porównania
Buckstabue
2
@Buckstabue Widzę, wydaje mi się, że mówimy o dwóch różnych kwestiach: 1) to*Setjest bardziej wydajne (przestrzeń i czas) niż distinct[By]dlatego, że zwraca Setbezpośrednio, zamiast używać Setwewnętrznie i konwertować je na a Listjako wartość zwracaną i 2) distinctByjest może być bardziej wydajne niż distinctpo prostu dlatego, że można uniknąć pełnego porównania równości obiektów. Oba są ważnymi punktami. Pobiegłem z twoim stwierdzeniem, że „z pewnością nie zawsze ma narzuty” i odpowiadałem na to i przeoczyłem, że porównujesz się distinctz distinctBy(a nie z to*Set).
mfulton26
1
@ mfulton26, masz rację. Najczęściej oznaczało, że czasami lepiej jest użyć listy + distinctBy niż Set, ponieważ Zestaw intensywnie korzystać z równych / hashcode, które potencjalnie mogłyby być drogie, aby zadzwonić
Buckstabue
1
W chwili pisania tego tekstu Iterable.distinctfaktycznie działa toMutableSet().toList()wewnętrznie. Więc nie martw się o wydajność :-)
Łukasz