reduce og aggregate
Andre måter å kombinere elementer på.
reduce og aggregate er en gratis leksjon i Scala for backendutvikling og funksjonell programmering på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Scala for backendutvikling og funksjonell programmering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Scala for backendutvikling og funksjonell programmering inneholder totalt 4 leksjoner.
Fra fold til reduce
Noen ganger ønsker De å kombinere elementer uten å angi en separat startverdi.
reduce bruker det første elementet som startakkumulator og kombinerer resten inn i den.
Det er en slankere slektning av fold for tilfeller der elementtypen og resultattypen er den samme.
Grunnleggende om reduce
reduce tar en binær funksjon (a, b) og folder den over samlingen uten en uttrykkelig startverdi.
For en sum legger den ganske enkelt alle elementene sammen.
val xs = List(1, 2, 3, 4)
val total = xs.reduce((a, b) => a + b)
@main def run(): Unit =
println(total) // 10Fellen med tomme samlinger
Fordi reduce ikke har noen startverdi, utløser et kall på en tom samling en UnsupportedOperationException.
fold og foldLeft er trygge på tomme samlinger fordi de faller tilbake på den angitte startverdien.
Bruk reduce bare når De vet at samlingen ikke er tom.
// List.empty[Int].reduce(_ + _)
// throws UnsupportedOperationException
List.empty[Int].foldLeft(0)(_ + _) // safe, returns 0reduceOption for sikkerhet
reduceOption returnerer en Option og gir None for en tom samling i stedet for å kaste et unntak.
Dette er den trygge måten å bruke reduce på når samlingen kan være tom.
val xs = List(5, 9, 2)
val maybeMax = xs.reduceOption(_ max _)
@main def run(): Unit =
println(maybeMax) // Some(9)reduceLeft og reduceRight
I likhet med fold har reduce retningsbestemte varianter.
reduceLeft kombinerer fra venstre mot høyre, mens reduceRight kombinerer fra høyre mot venstre. Vanlig reduce gir ingen garanti for rekkefølgen i parallelle samlinger, så bruk den eksplisitte varianten når retningen er viktig.
val xs = List(1, 2, 3)
val l = xs.reduceLeft(_ - _) // (1-2)-3 = -4
val r = xs.reduceRight(_ - _) // 1-(2-3) = 2
@main def run(): Unit =
println((l, r)) // (-4, 2)Hvorfor aggregate finnes
fold og reduce krever at akkumulator- og elementtypene henger enkelt sammen.
aggregate er den mest generelle fold-varianten: Den lar akkumulatoren ha en annen type OG forteller Scala hvordan delakkumulatorer skal slås sammen, noe som er viktig ved parallell behandling.
Signaturen til aggregate
aggregate tar et startobjekt, en seqop som folder et element inn i akkumulatoren, og en combop som slår sammen to akkumulatorer.
I en sekvensiell samling brukes combop sjelden. I en parallell samling slår den sammen resultatene fra hver del.
val xs = List(1, 2, 3, 4)
val sum = xs.aggregate(0)(
(acc, x) => acc + x, // seqop
(a, b) => a + b // combop
)
@main def run(): Unit = println(sum) // 10aggregate med en annen type
Her folder aggregate en liste med ord til en samlet lengde av typen Int.
seqop legger til lengden på hvert ord, mens combop legger sammen to delsummer.
Akkumulatortypen (Int) er forskjellig fra elementtypen (String).
val words = List("hi", "there", "you")
val chars = words.aggregate(0)(
(acc, w) => acc + w.length,
(a, b) => a + b
)
@main def run(): Unit = println(chars) // 10Parallell aggregering
Den virkelige styrken til aggregate kommer til syne med parallelle samlinger.
Hver tråd folder sin egen del med seqop, og deretter slås delene sammen med combop. De to funksjonene lar Scala dele opp og sette sammen arbeidet på en trygg måte.
// Conceptual: par splits the work
// val n = data.par.aggregate(0)(_ + _.length, _ + _)
// seqop runs per chunk, combop merges chunk resultsVelge riktig verktøy
Bruk reduce eller reduceOption når resultattypen er lik elementtypen og kombinasjonen er associativ.
Bruk foldLeft når du trenger et startobjekt eller en annen resultattype i sekvensiell behandling.
Bruk aggregate når akkumulator- og elementtypene er forskjellige, og du ønsker sammenslåing som egner seg for parallell behandling.
// reduce: same type, non-empty, associative
// foldLeft: seed + different type, sequential
// aggregate: different type + parallel mergeKombinere i én gjennomgang
aggregate kan beregne flere ting samtidig ved å akkumulere i en tuppel.
Her får vi både summen og antallet i én gjennomgang, og slår sammen tupler i combop.
val xs = List(2, 4, 6, 8)
val (s, c) = xs.aggregate((0, 0))(
(acc, x) => (acc._1 + x, acc._2 + 1),
(a, b) => (a._1 + b._1, a._2 + b._2)
)
@main def run(): Unit = println((s, c)) // (20, 4)Kort kontroll
Avgjør hvilken operasjon som er tryggest for en liste som kan være tom.
Oppsummering
reduce kombinerer elementer uten et startobjekt og bruker det første elementet som start. Den kaster et unntak for en tom samling, mens reduceOption returnerer None.
aggregate er den mest generelle fold-varianten: et startobjekt, en seqop som folder inn elementer, og en combop som slår sammen delakkumulatorer ved parallell behandling.
Velg reduce for associativ kombinasjon av samme type, foldLeft for sekvensielle fold-operasjoner med startobjekt, og aggregate når typene er forskjellige eller behandlingen skal være parallell.
Lær deg Scala med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 39
- Leksjoner
- 143
Ofte stilte spørsmål
Er leksjonen «reduce og aggregate» gratis?
Ja – hele teksten i «reduce og aggregate» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Scala for backendutvikling og funksjonell programmering-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Scala for backendutvikling og funksjonell programmering inneholder totalt 4 leksjoner.
Hva lærer jeg i «reduce og aggregate»?
Andre måter å kombinere elementer på. Du øver på Scala for backendutvikling og funksjonell programmering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Scala for backendutvikling og funksjonell programmering?
Ingen tidligere erfaring er nødvendig. Scala for backendutvikling og funksjonell programmering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «reduce og aggregate»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Scala for backendutvikling og funksjonell programmering-leksjonen?
Ja. Alle Scala for backendutvikling og funksjonell programmering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Tenk rekursivt
- Akkumulatormønstre
- foldLeft og foldRight
- reduce og aggregate