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ż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ść :-)
Odpowiedzi:
Użyj
distinct
funkcji rozszerzenia :val a = arrayOf("a", "a", "b", "c", "c") val b = a.distinct() // ["a", "b", "c"]
Istnieje również
distinctBy
funkcja, 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
,toMutableSet
a jeśli nie trzeba oryginalną kolejność być zachowane,toHashSet
. Te funkcje tworząSet
zamiast aList
i powinny być nieco bardziej wydajne niżdistinct
.Może ci się przydać:
źródło
toSet
lubtoMutableSet
które mają mniejszy narzut niż,distinct
a jeśli zamówienie nie ma znaczenia, możesz użyćtoHashSet
.to*Set
jest bardziej wydajne (przestrzeń i czas) niżdistinct[By]
dlatego, że zwracaSet
bezpośrednio, zamiast używaćSet
wewnętrznie i konwertować je na aList
jako wartość zwracaną i 2)distinctBy
jest może być bardziej wydajne niżdistinct
po 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ędistinct
zdistinctBy
(a nie zto*Set
).Iterable.distinct
faktycznie działatoMutableSet().toList()
wewnętrznie. Więc nie martw się o wydajność :-)