Del en liste i deler i Kotlin

1. Introduksjon

La oss si at vi har en serie som [A B C D E F] og vi ønsker å dele elementene opp i separate grupper, som [[A B C D E F]] eller [[A B C D E F]].

I denne opplæringen oppnår vi dette mens vi undersøker noen forskjeller mellom Kotlins groupBy, chunked, og vindu.

2. Dele en liste i en liste over par

For eksemplene våre bruker vi to lister - en med et jevnt antall elementer og en med et ulikt antall elementer:

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

Det er klart at vi kan dele vårt evenList i nøyaktig tre par. Imidlertid vår ujevn liste vil ha ett ekstra element.

Resten av denne delen vil vi se forskjellige implementeringer for å dele våre to lister, inkludert hvordan de håndterer det ekstra elementet i ujevn liste.

2.1. Ved hjelp av gruppe av

La oss først implementere en løsning med groupBy. Vi oppretter en liste med stigende tall og bruk gruppe av å dele dem:

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

Dette gir ønsket resultat:

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

Hvordan virker det? Vi vil, gruppe av utfører den medfølgende funksjonen (it + 1) / 2 på hvert element:

  • (1 + 1) / 2 = 1
  • (2 + 1) / 2 = 1,5, som er avrundet til 1
  • (3 + 1) / 2 = 2
  • (4 + 1) / 2 = 2,5, som er avrundet til 2
  • (5 + 1) / 2 = 3
  • (6 + 1) / 2 = 3,5, som er avrundet til 3

Deretter, gruppe av grupperer elementene i listen som ga samme resultat.

Nå, når vi gjør det samme med en ujevn liste:

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

Vi får alle parene og ett ekstra element:

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

Men, hvis vi går litt lenger med noen tilfeldige tall:

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

Vi får noe som er helt uønsket:

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

Årsaken er enkel; bruker (it + 1) / 2 funksjon på hvert element gir: 1, 2, 4, 10, 12, 15. Alle resultatene er forskjellige, så ingen elementer er gruppert sammen.

Når vi bruker vår evenList eller ujevn liste, det er enda verre - koden kompileres ikke, da funksjonen ikke kan brukes på Strenger.

2.2. Ved hjelp av gruppe av og medIndex

Virkelig, hvis vi ønsker å gruppere en vilkårlig liste i par, vi ønsker ikke å endre verdi av vår funksjon, men den indeks:

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

Dette returnerer listen over par vi ønsker:

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

Videre, hvis vi bruker ujevn liste, får vi til og med vårt separate element:

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

2.3. Ved hjelp av gruppe av Med foldIndexed

Vi kan gå et skritt videre enn bare å bruke indeks og programmer litt mer med foldIndexed for å lagre noen tildelinger:

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

Mens litt mer ordentlig, de foldIndexed løsning utfører ganske enkelt operasjonen på hvert element, mens medIndex funksjon oppretter først en iterator og bryter inn hvert element.

2.4. Ved hjelp av klumpete

Men vi kan gjøre dette mer elegant med klumpete. Så la oss bruke metoden på vår evenList:

evenList.chunked (2)

De evenList gir oss de parene vi ønsker:

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

Mens ujevn liste gir oss parene og det ekstra elementet:

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

2.5. Ved hjelp av vindu

Og klumpete fungerer veldig bra, men noen ganger trenger vi litt mer kontroll.

For eksempel må vi kanskje spesifisere om vi bare vil ha par, eller om vi vil inkludere det ekstra elementet. De vindu metoden gir oss en partialWindows Boolsk, som indikerer om vi vil ha delvis resultat eller ikke.

Som standard, partialWindows er falsk. Så følgende uttalelser gir det samme resultatet:

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

Begge returnerer listen uten det separate elementet:

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

Til slutt, når vi setter partialWindows til ekte for å inkludere delresultatet:

unevenList.windowed (2, 2, sant)

Vi får listen over par pluss det separate elementet:

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

3. Konklusjon

Ved hjelp av gruppe av er en fin programmeringsøvelse, men den kan være ganske feilutsatt. Noen av feilene kan løses ved å bruke en indeks.

For å optimalisere koden kan vi til og med bruke foldIndexed. Dette resulterer imidlertid i enda mer kode. Heldigvis, den klumpete metoden gir oss den samme funksjonaliteten utenom boksen.

Videre, den vindu metoden gir flere konfigurasjonsalternativer. Hvis det er mulig, er det best å bruke klumpete metoden, og hvis vi trenger ytterligere konfigurasjon, bør vi bruke vindu metode.

Som vanlig er hele kildekoden tilgjengelig på GitHub.


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