Podijelite popis na dijelove u Kotlinu

1. Uvod

Recimo da imamo niz poput [a B C D E F] i želimo podijeliti elemente u zasebne skupine, poput [[a B C D E F]] ili [[a B C D E F]].

U ovom uputstvu postići ćemo to istražujući neke razlike između Kotlinovih grupaBy, chunked, i prozorski.

2. Dijeljenje popisa na popis parova

Za naše primjere koristit ćemo dva popisa - jedan s parnim brojem elemenata i jedan s neparnim brojem elemenata:

val evenList = listOf (0, "a", 1, "b", 2, "c"); val unevenList = listOf (0, "a", 1, "b", 2, "c", 3);

Jasno, možemo podijeliti svoje evenList u točno tri para. Međutim, naša neujednačenaPopis imat će jedan dodatni element.

U ostatku ovog odjeljka vidjet ćemo razne implementacije za razdvajanje naša dva popisa, uključujući kako se bave dodatnim elementom u neujednačenaPopis.

2.1. Koristeći grupaBy

Prvo, provedimo rješenje s groupBy. Stvorit ćemo popis s rastućim brojevima i koristiti grupaBy da ih podijelimo:

val numberList = listOf (1, 2, 3, 4, 5, 6); numberList.groupBy {(it + 1) / 2} .vrijednosti

To daje željeni rezultat:

[[1, 2], [3, 4], [5, 6]]

Kako radi? Dobro, grupaBy izvršava isporučenu funkciju (it + 1) / 2 na svakom elementu:

  • (1 + 1) / 2 = 1
  • (2 + 1) / 2 = 1,5, što je zaokruženo na 1
  • (3 + 1) / 2 = 2
  • (4 + 1) / 2 = 2,5, što je zaokruženo na 2
  • (5 + 1) / 2 = 3
  • (6 + 1) / 2 = 3,5, što je zaokruženo na 3

Zatim, grupaBy grupira elemente s popisa koji su dali isti rezultat.

Sada, kada to učinimo s neravnim popisom:

val numberList = listOf (1, 2, 3, 4, 5, 6, 7); numberList.groupBy {(it + 1) / 2} .vrijednosti

Dobivamo sve parove i jedan dodatni element:

[[1, 2], [3, 4], [5, 6], [7]]

Ali, ako idemo malo dalje s nekim slučajnim brojevima:

val numberList = listOf (1, 3, 8, 20, 23, 30); numberList.groupBy {(it + 1) / 2} .vrijednosti

Dobit ćemo nešto što je potpuno nepoželjno:

[[1], [3], [8], [20], [23], [30]]

Razlog je jednostavan; primjenom (it + 1) / 2 funkcija na svakom elementu daje: 1, 2, 4, 10, 12, 15. Svi se rezultati razlikuju, tako da se niti jedan element ne grupira.

Kad koristimo svoje evenList ili neujednačenaPopis, još je gore - kod se ne sastavlja, jer se funkcija ne može primijeniti na Žice.

2.2. Koristeći grupaBy i withIndex

Stvarno, ako želimo grupirati proizvoljan popis u parove, ne želimo mijenjati vrijednost po našoj funkciji, ali indeks:

evenList.withIndex () .groupBy {it.index / 2} .map {it.value.map {it.value}}

Ovo vraća popis parova koje želimo:

[[0, "a"], [1, "b"], [2, "c"]]

Nadalje, ako koristimo neujednačenaPopis, čak dobivamo i naš zasebni element:

[[0, "a"], [1, "b"], [2, "c"], [3]]

2.3. Koristeći grupaBy S foldIndexed

Možemo ići korak dalje od pukog korištenja indeks i programirajte malo više sa foldIndexed da biste spremili neka izdvajanja:

evenList.foldIndexed (ArrayList(evenList.size / 2)) {index, acc, item -> if (index% 2 == 0) {acc.add (ArrayList (2))} acc.last (). add (item) acc}

Iako malo opširniji, the foldIndexed rješenje jednostavno izvodi operaciju na svakom elementu, dok je withIndex funkcija prvo kreira iterator i obavija svaki element.

2.4. Koristeći komadan

Ali, to možemo učiniti elegantnije komadan. Dakle, primijenimo metodu na našu evenList:

evenList.chunked (2)

The evenList pruža nam parove koje želimo:

[[0, "a"], [1, "b"], [2, "c"]]

Dok neujednačenaPopis daje nam parove i dodatni element:

[[0, "a"], [1, "b"], [2, "c"], [3]]

2.5. Koristeći prozorski

I komadan djeluje jako dobro, ali ponekad nam treba malo više kontrole.

Na primjer, možda ćemo trebati odrediti želimo li samo parove ili želimo uključiti dodatni element. The prozorski metoda nam pruža a djelomičniWindows Booleova, što ukazuje na to želimo li djelomični rezultat ili ne.

Prema zadanim postavkama, djelomičniWindows je lažno. Dakle, sljedeće izjave daju isti rezultat:

evenList.windowed (2, 2) unevenList.windowed (2, 2, false)

Oboje vraćaju popis bez zasebnog elementa:

[[0, "a"], [1, "b"], [2, "c"]]

Napokon, kad krenemo djelomičniWindows do pravi uključiti djelomični rezultat:

unevenList.windowed (2, 2, istina)

Dobit ćemo popis parova plus zasebni element:

[[0, "a"], [1, "b"], [2, "c"], [3]]

3. Zaključak

Koristeći grupaBy je lijepa vježba programiranja, ali može biti sklona pogreškama. Neke se pogreške mogu riješiti jednostavnim korištenjem indeks.

Za optimizaciju koda možemo čak i koristiti foldIndexed. Međutim, to rezultira još više koda. Srećom, komadan metoda nudi nam istu funkcionalnost odmah po narudžbi.

Štoviše, prozorski metoda pruža dodatne mogućnosti konfiguracije. Ako je moguće, najbolje je koristiti komadan metodu, a ako trebamo dodatnu konfiguraciju, trebali bismo koristiti prozorski metoda.

Kao i obično, puni izvorni kod dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found