Skrevet Av Reinder De Vries 12. juli 2020 I App Development, Swift

FlatMap Og CompactMap Forklart I Swift

Swift har en rekke funksjoner som er nyttige for å transformere samlinger og sekvenser. I denne opplæringen diskuterer vi map(_:), flatMap(_:) og compactMap(_:).

Her er hva vi skal fokusere på:

  1. hvordan map(_:) forvandler en samling eller sekvens ved å bruke en nedleggelse til den
  2. hvordan flatMap(_:) kan flate en input array, etter ringer map(_:)
  3. hvordan compactMap(_:) fjerner nil fra input array

i en tidligere tutorial, har vi diskutert hvordan du kan bruke filter(_:) og reduce(_:). Disse høyere ordensfunksjonene er super nyttige for å transformere samlinger, på en kortfattet og innsiktsfull måte.

Klar? Kom igjen.

  1. Bruke Kartfunksjonen I Swift
  2. Bruke FlatMap-Funksjonen
  3. Bruke CompactMap-Funksjonen
  4. Hvorfor Bruke FlatMap og CompactMap?
  5. Videre Lesing

Ikke kjent med lukninger eller høyere ordensfunksjoner? Sørg for å lese opp på de første:

  • Den Ultimate Guiden Til Nedleggelser I Swift
  • Kart, Reduser Og Filtrer I Swift

Ved Å bruke Kartfunksjonen I Swift

som en rask oppdatering på høyere ordensfunksjoner i Swift, er vårt utgangspunkt map(_:) – funksjonen . Denne funksjonen bruker en transformasjon til hvert av elementene i en sekvens, for eksempel en matrise eller ordbok.

her er et eksempel:

la tall =
la resultat = tall.kart({ $0 * $0 })
skriv ut (resultat)
Skjul advarsler

La oss bryte det ned:

Først lager vi en matrise numbers med noen få heltallverdier. Deretter kalles funksjonen map(_:)numbers og resultatet er tildelt result.

funksjonen map(_:) har en parameter, en lukning, som returnerer resultatet av . tilsvarer den første parameteren for lukkingen, dvs. tallet fra numbers som blir transformert.

vi beregner kvadratet av hvert tall i numbers. I hovedsak kalles operasjonen på hvert nummer i numbers, og den resulterende matrisen er tildelt result. Du transformerer-eller » kartlegging – – en matrise til en annen.

Transformere en matrise med map(_:) ligner på å bruke en for loop, men mye mer konsis. Som dette:

let numbers = var result = ()for number in numbers { result += }print(result)

Her er en annen måte å se på det. Med map(_:) blir inntastingsgruppen av tall omdannet til en annen rekke tall. Som dette:

2 => 2 * 2 => 43 => 3 * 3 => 94 => 4 * 4 => 165 => 5 * 5 => 25

Funksjoner som map(_:) kalles høyere ordensfunksjoner, fordi de tar en funksjon som input i motsetning til vanlige verdier. Høyere ordensfunksjoner kan også utdata funksjoner, som er nyttig for et programmeringsparadigme kalt funksjonell programmering.

Teknisk kan du ringe høyere ordensfunksjoner som map(_:) på hvilken som helst sekvens. Dette inkluderer samlinger som arrays, ordbøker og sett, områder som 1...100 og såkalte iteratorer. Alt som ser ut som en» liste » av verdier, i utgangspunktet.

vi vil diskutere hvorfor høyere ordensfunksjoner er nyttige på slutten av denne opplæringen. La oss først gå videre for å lære om flatMap(_:) og compactMap(_:).

Bli ansatt som iOS-utvikler

Lær å bygge iOS 14-apper med Swift 5

Registrer deg for mitt iOS-utviklingskurs, og lær hvordan du starter din karriere som profesjonell iOS-utvikler.

Ved Hjelp Av FlatMap-Funksjonen

flatMap(_:) – funksjonen ligner map(_:), bortsett fra at den «flater» den resulterende matrisen. Her er et eksempel:

la tall =,,]
la resultat = tall.flatMap ({$0})
skriv ut (resultat)
Skjul advarsler

koden ovenfor starter med et nestet utvalg av heltall. Matrisen numbers består av en matrise på 3 matriser, som hver inneholder 3 tall.

lukkingen { } returnerer bare det første argumentet for lukkingen, dvs. de enkelte nestede arrays. Ingen transformasjon eller operasjon skjer. Når du ringer flatMap(_:)numbers – arrayet, i stedet for map(_:), ender du med et flatt utvalg av individuelle tall. I motsetning til input-matrisen numbers inneholder ikke resultatmatrisen nestede matriser!

La oss se på et annet eksempel. Tenk deg at du jobber med 4 grupper sjiraffer, og vil lage en enkelt gruppe sjiraffer som er høyere enn en viss høyde. Slik gjør du det:

la giraffer =,,]
la høyeste = sjiraffer.flatMap ({ $0.filtrer({ $0 > 10 }) })
print (høyeste)
Skjul advarsler

se hvordan giraffes inneholder en rekke matriser? I koden ovenfor kalles funksjonen filter(_:) på hvert nestet array inne giraffes. Vi vil bare ha heltall (giraffer!) som er større enn 10. De resulterende arrays er flatet inn i en «flat» array, og tilordnet til tallest.

Tenk på hva som ville skje hvis vi hadde brukt map(_:) i stedet for flatMap(_:). Det resulterende arrayet ville ikke bli flatt. I stedet ville det være dette:

, , ]

det er viktig å merke seg at funksjonen flatMap(_:) kaller map(_:) på matriseelementene først, og deretter flater den ut. Det er derfor noe som følgende ikke fungerer:

let numbers = , , ]let result = numbers.flatMap({  * 2 })

i koden ovenfor refererer til arrays inside numbers. Å multiplisere en matrise med to er umulig, så det er derfor denne koden ikke virker.

det er smart å tenke på flatmapping som å se en matrise i en mindre dimensjon. Du starter med en todimensjonal matrise, og ender opp med en endimensjonal matrise etter flatMap(_:).

hva med å bruke flatMap(_:) med opsjoner? La oss se på det neste.

navnet «kompakt kart» er basert på ideen om at fjerning av nil elementer fra en matrise gjør matrisen mer kompakt. På samme måte kommer navnet «flatt kart» fra å flate matrisen. Og «kartlegging» er et konsept fra matematikk, hvor du knytter verdiene i ett sett med et annet sett.

Ved Hjelp Av CompactMap-Funksjonen

compactMap(_:) – funksjonen fjerner nil – verdier fra inndataarrayen. Det er super nyttig når du arbeider med optionals.

Før Swift 4.1, funksjonen flatMap(_:) (ovenfor) kan også brukes til å filtrere ut nil verdier fra flattede arrays. Siden Swift 4.1 + bruker du nå eksplisitt compactMap(_:) til dette formålet.

her er et eksempel:

la tall =
la resultat = tall.compactMap ({Int ($0)})
skriv ut (resultat)
Skjul advarsler

Se hva som skjer? Den viktigste delen av koden er Int(). Dette tar en individuell streng fra numbers med og forsøker å konvertere til et heltall, med Int() initializer.

dette Int() initializer er failable: det kan returnere nil – en valgfri-så returtypen er Int?. Som et resultat er returtypen for tilordning transformasjon – en rekke valgfrie heltall.

funksjonen compactMap(_:) fjerner automatisk nil elementer fra den returnerte matrisen, etter å ha ringt map(_:) på den. Som sådan er returtypen ikke valgfri.

i koden ovenfor er typen result. Hvis du ville ha brukt map(_:), ville returtypen ha vært . Og du ville ha behov for et ekstra skritt for å pakke ut verdiene fra matrisen, for å jobbe med dem.

Hvorfor Bruke FlatMap og CompactMap?

før vi diskuterer den virkelige verden bruk tilfeller av flatmap og compactmap, la oss gjøre en rask oppsummering av disse høyere ordens funksjoner og deres formål.

  1. map(_:) – funksjonen bruker en lukking på en inndatasamling, og returnerer den transformerte samlingen
  2. flatMap(_:) – funksjonen gjør det samme, og den flater også den resulterende samlingen
  3. compactMap(_:) – funksjonen gjør det samme som map(_:), og den fjerner også nil fra den resulterende samlingen

arbeide med map(_:), flatMap(_:) og compactMap(_:) i det abstrakte gjør det noen ganger vanskelig å forestille seg deres praktiske brukstilfeller. La oss diskutere hvorfor du vil bruke dem.

Bruk av funksjoner som kart(_:) for å bruke transformasjoner til sekvenser har noen fordeler:

  • det er mer konsist enn å bruke en for loop, fordi du ikke trenger midlertidige variabler og en multi-line for in { } blokk.
  • du kan vanligvis skrive et anrop til map(_:) på en linje, noe som (vanligvis) gjør koden mer lesbar.
  • Funksjoner som map(_:) kan lenkes, slik at du kan bruke flere transformasjoner til en sekvens en etter en.

generelt er høyere ordensfunksjoner nyttige fordi de lar deg bruke en funksjon til en sekvens av verdier. I stedet for å kode transformasjonen prosedyre, kan du bare bruke funksjonen og få et resultat tilbake.

den mest praktiske brukssaken for flatMap(_:) arbeider med inndataverdier som er gruppert eller nestet, men utdataverdien du vil ha, må være endimensjonal.

Du kan for eksempel i en musikkapp ha 3 arrays: sanger, artister og spillelister. Du kombinerer dem i en matrise, ring flatMap(_:) på den, velg sanger, artister og spillelister som isFavorite er true, og ende opp med en flat liste over elementer som har blitt favorisert.

et praktisk brukstilfelle for compactMap(_:) arbeider med en transformasjon som kan returnere nil. Du sparer deg selv noen få trivielle trinn ved å la compactMap(_:) filtrere ut nil verdier umiddelbart. En ekstra fordel er compactMap(_:)‘s ikke-valgfrie returtype; funksjonen filter(_:), til sammenligning, ville ha returnert en valgfri verdi hvis du filtrerte ut nil.

du kan kombinere flatMap(_:) og compactMap(_:), og til og med filter(_:) eller reduce(_:_:). Tenk deg at du bygger en sosial media-app. Du vil lage en tidslinje av innlegg for en bruker. Du bruker 3 spørringer til å velge post-Ider for brukeren, for eksempel fra følgerinnlegg, annonser og trendingemner.

  • du kan bruke map(_:) for å utvide Disse Idene til faktiske Post objekter
  • du kan bruke flatMap(_:) til å slå sammen de 3 gruppene i en samling
  • du kan bruke compactMap(_:) til å forkaste innlegg som ikke kunne utvides

Ryddig!

Bli ansatt som iOS-utvikler

Lær å bygge iOS 14-apper med Swift 5

Registrer deg for mitt iOS-utviklingskurs, og lær hvordan du starter din karriere som profesjonell iOS-utvikler.

Videre Lesing

det er verdt å lære om map(_:), flatMap(_:) og compactMap(_:) , fordi de gjør koden din mer kortfattet og lesbar. Du kan legge til mer funksjonell programmering i appens kode. Når du blir vant til dem, kan du ikke tro at du kunne gjøre arbeidet ditt uten dem.

spesielt forskjellene mellom map(_:), flatMap(_:) og compactMap(_:) er verdt å peke på. Den første bruker en transformasjon til en sekvens, den andre flater den resulterende matrisen ,og den tredje fjerner nil verdier før resultatet returneres. Fantastisk!

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.