Opdel en liste i dele i Kotlin

1. Introduktion

Lad os sige, at vi har en matrix som [a, b, c, d, e, f] og vi vil opdele elementerne i separate grupper, ligesom [[a, b], [c, d], [e, f]] eller [[a, b, c], [d], [e, f]].

I denne vejledning opnår vi dette, mens vi undersøger nogle forskelle mellem Kotlins gruppeBy, chunked, og vinduesvindue.

2. Opdeling af en liste i en liste over par

I vores eksempler bruger vi to lister - en med et lige antal elementer og en med et ulige antal 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 vores evenList i nøjagtigt tre par. Men vores ujævn liste vil have et ekstra element.

I resten af ​​dette afsnit vil vi se forskellige implementeringer til opdeling af vores to lister, herunder hvordan de håndterer det ekstra element i ujævn liste.

2.1. Ved brug af groupBy

Lad os først implementere en løsning med groupBy. Vi opretter en liste med stigende tal og brug groupBy at opdele dem:

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

Dette giver det ønskede resultat:

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

Hvordan virker det? Godt, groupBy udfører den medfølgende funktion (it + 1) / 2 på hvert element:

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

Derefter, groupBy grupperer elementerne på listen, der gav det samme resultat.

Nu, når vi gør det samme med en ujævn liste:

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

Vi får alle parene og et ekstra element:

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

Men, hvis vi går lidt længere med nogle tilfældige tal:

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

Vi får noget, der er helt uønsket:

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

Årsagen er enkel; anvender (it + 1) / 2 funktion på hvert element giver: 1, 2, 4, 10, 12, 15. Alle resultater er forskellige, så ingen elementer er grupperet sammen.

Når vi bruger vores evenList eller ujævn liste, det er endnu værre - koden kompileres ikke, da funktionen ikke kan anvendes til Strenge.

2.2. Ved brug af groupBy og medIndex

Virkelig, hvis vi vil gruppere en vilkårlig liste i par, vi ønsker ikke at ændre værdi ved vores funktion, men 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"]]

Desuden, hvis vi bruger ujævn liste, vi får endda vores separate element:

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

2.3. Ved brug af groupBy Med foldindekseret

Vi kan gå et skridt videre end bare at bruge indeks og programmer lidt mere med foldindekseret for at gemme nogle tildelinger:

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

Mens lidt mere detaljeret, det foldindekseret løsning udfører simpelthen operationen på hvert element, hvorimod medIndex funktion opretter først en iterator og indpakker hvert element.

2.4. Ved brug af klumpet

Men vi kan gøre dette mere elegant med klumpet. Så lad os anvende metoden på vores evenList:

evenList.chunked (2)

Det evenList giver os de par, vi ønsker:

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

Mens ujævn liste giver os parene og det ekstra element:

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

2.5. Ved brug af vinduesvindue

Og klumpet fungerer rigtig godt, men nogle gange har vi brug for lidt mere kontrol.

For eksempel kan det være nødvendigt at angive, om vi kun vil have par, eller om vi vil inkludere det ekstra element. Det vinduesvindue metode giver os en partialWindows Boolsk, hvilket indikerer, om vi vil have delresultatet eller ej.

Som standard, partialWindows er falsk. Så følgende udsagn giver det samme resultat:

evenList.windowed (2, 2) ujævnList.windowed (2, 2, false)

Begge returnerer listen uden det separate element:

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

Endelig, når vi sætter partialWindows til rigtigt at inkludere det delvise resultat:

unevenList.windowed (2, 2, sandt)

Vi får listen over par plus det separate element:

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

3. Konklusion

Ved brug af groupBy er en god programmeringsøvelse, men det kan være ret fejlbehæftet. Nogle af fejlene kan løses ved blot at bruge en indeks.

For at optimere koden kan vi endda bruge foldindekseret. Dette resulterer dog i endnu mere kode. Heldigvis klumpet metoden giver os den samme funktionalitet uden for kassen.

Desuden er vinduesvindue metode giver yderligere konfigurationsindstillinger. Hvis det er muligt, er det bedst at bruge klumpet metode, og hvis vi har brug for yderligere konfiguration, skal vi bruge vinduesvindue metode.

Som sædvanlig er den fulde kildekode tilgængelig på GitHub.


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