scris de Reinder de Vries pe 12 iulie 2020 în dezvoltarea aplicațiilor, Swift

FlatMap și CompactMap explicate în Swift

Swift are o grămadă de funcții care sunt utile pentru transformarea colecțiilor și secvențelor. În acest tutorial, vom discuta map(_:), flatMap(_:)și compactMap(_:).

Iată pe ce ne vom concentra:

  1. cum map(_:) transformă o colecție sau o secvență prin aplicarea unei închideri
  2. cum flatMap(_:) poate aplatiza o matrice de intrare, după apelarea map(_:)
  3. cum compactMap(_:) elimină nil din matricea de intrare

într-un tutorial anterior, am discutat despre modul în care puteți utiliza filter(_:) și reduce(_:). Aceste funcții de ordin superior sunt foarte utile pentru transformarea colecțiilor, într-un mod concis și perspicace.

gata? Să mergem.

  1. utilizarea funcției Map în Swift
  2. utilizarea funcției FlatMap
  3. utilizarea funcției CompactMap
  4. de ce să folosiți FlatMap și CompactMap?
  5. lecturi suplimentare

nu sunteți încă familiarizați cu închiderile sau funcțiile de ordin superior? Asigurați-vă că pentru a citi pe cei mai întâi:

  • ghidul final de închidere în Swift
  • harta, Reduce și se filtrează în Swift

folosind funcția Map din Swift

ca o actualizare rapidă a funcțiilor de ordin superior din Swift, punctul nostru de plecare este funcția map(_:). Această funcție aplică o transformare fiecărui element dintr-o secvență, cum ar fi o matrice sau un dicționar.

Iată un exemplu:

să numere =
să rezultat = numere.hartă({ $0 * $0 })
imprimare (rezultat)
ascunde avertismente

să rupe că în jos:

în primul rând, vom crea o matrice numbers cu câteva valori întregi. Apoi, funcția map(_:) este apelată la numbersși rezultatul acesteia este atribuit la result.

funcția map(_:) are un parametru, o închidere, care returnează rezultatul . corespunde primului parametru al închiderii, adică numărul de la numbers care este transformat.

calculăm pătratul fiecărui număr în numbers. În esență, operația este apelată la fiecare număr din numbers, iar matricea rezultată este atribuită result. Transformi-sau „mapezi” – o matrice în alta.

transformarea unei matrice cu map(_:) este similară cu utilizarea unei bucle for, dar mult mai concisă. Ca aceasta:

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

Iată un alt mod de a privi. Cu map(_:), matricea de intrare a numerelor este transformată într-o altă matrice de numere. Ca aceasta:

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

funcții precum map(_:) sunt numite funcții de ordin superior, deoarece iau o funcție ca intrare, spre deosebire de valorile obișnuite. Funcțiile de ordin superior pot, de asemenea, să emită funcții, ceea ce este util pentru o paradigmă de programare numită Programare funcțională.

tehnic, puteți apela funcții de ordin superior, cum ar fi map(_:) pe orice secvență. Aceasta include colecții precum tablouri, dicționare și seturi, intervale precum 1...100 și așa-numitele iteratoare. Orice lucru care arată ca o” listă ” de valori, practic.

vom discuta De ce funcțiile de ordin superior sunt utile la sfârșitul acestui tutorial. Să trecem mai întâi pentru a afla despre flatMap(_:) și compactMap(_:).

angajați-vă ca dezvoltator iOS

Aflați cum să construiți Aplicații iOS 14 cu Swift 5

Înscrieți-vă la cursul meu de dezvoltare iOS și aflați cum să vă începeți cariera ca dezvoltator iOS profesionist.

folosind funcția FlatMap

funcția flatMap(_:) este similară cu map(_:) cu excepția faptului că „aplatizează” matricea rezultată. Iată un exemplu:

să numere=,,]
să rezultat = numere.flatMap ({ $0})
imprimare (rezultat)
ascundeți avertismentele

codul de mai sus începe cu o matrice imbricată de numere întregi. Matricea numbers constă dintr-o matrice de 3 matrice, care conține fiecare 3 numere.

închiderea { } returnează pur și simplu primul argument al închiderii, adică matricele imbricate individuale. Nici o transformare sau operațiune nu se întâmplă. Când apelați flatMap(_:) pe numbers matrice deși, în loc de map(_:), va termina cu o matrice aplatizate de numere individuale. Spre deosebire de matrice de intrare numbers, matrice rezultat nu conține matrice imbricate!

să ne uităm la un alt exemplu. Imaginați-vă că lucrați cu 4 grupuri de girafe și doriți să creați un singur grup de girafe care sunt mai înalte decât o anumită înălțime. Iată cum faci asta:

să girafe=,,]
să cel mai înalt = girafe.flatMap ({ $0.filtru({ $0 > 10 }) })
print (cel mai înalt)
ascundeți avertismentele

vedeți cum giraffes conține o matrice de matrice? În codul de mai sus, funcția filter(_:) este apelată pe fiecare matrice imbricată din interiorul giraffes. Vrem doar numere întregi (girafe!) care sunt mai mari decât 10. Matricele rezultate sunt aplatizate într-o matrice” plată ” și atribuite tallest.

luați în considerare ce s-ar întâmpla dacă am fi folosit map(_:) în loc de flatMap(_:). Matricea rezultată nu ar fi aplatizată. În schimb, ar fi aceasta:

, , ]

este important să rețineți că funcția flatMap(_:) apelează mai întâi map(_:) pe elementele matrice și apoi o aplatizează. De aceea, ceva de genul următor nu funcționează:

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

în codul de mai sus, se referă la matricele din interiorul numerelor. Înmulțirea unei matrice cu două este imposibilă, deci de aceea acest cod nu funcționează.

este inteligent să se gândească la flatmapping ca văzând o matrice într-o dimensiune mai puțin. Începi cu o matrice bidimensională și sfârșești cu o matrice unidimensională după flatMap(_:).

ce zici de utilizarea flatMap(_:) cu opțiuni? Să ne uităm la asta în continuare.

numele „hartă compactă” se bazează pe ideea că eliminarea elementelor nil dintr-o matrice face matricea mai compactă. La fel, Numele „hartă plană” provine din aplatizarea matricei. Și „maparea” este un concept din matematică, unde asociați valorile dintr-un set cu un alt set.

utilizarea funcției CompactMap

funcția compactMap(_:) elimină valorile nil din matricea de intrare. Este foarte util atunci când se lucrează cu opțiuni.

Înainte De Swift 4.1, funcția flatMap(_:) (de mai sus) ar putea fi, de asemenea, utilizată pentru a filtra valorile nil din tablourile aplatizate. Începând cu Swift 4.1+, acum utilizați explicit compactMap(_:) în acest scop.

Iată un exemplu:

să numere =
să rezultat = numere.compactMap ({int ($0)})
imprimare (rezultat)
ascunde avertismente

vezi ce se întâmplă? Cea mai importantă parte a codului este Int(). Aceasta ia un șir individual de la numbers cu și încearcă să convertească la un număr întreg, cu inițializatorul Int().

acest Int() inițializator este failable: se poate întoarce nil – un opțional – deci tipul său de returnare este Int?. Ca rezultat, tipul de întoarcere al transformării de mapare este – o serie de numere întregi opționale.

funcția compactMap(_:) elimină automat elementele nil din matricea returnată, după ce a apelat map(_:) pe ea. Ca atare, tipul de retur este non-opțional.

în codul de mai sus, tipul de resulteste . Dacă ați fi folosit map(_:), tipul de retur ar fi fost . Și ați fi avut nevoie de un pas suplimentar pentru a desface valorile din matrice, pentru a lucra cu ele.

de ce să folosiți FlatMap și CompactMap?

înainte de a discuta despre cazurile de utilizare din lumea reală a flatmap și compactmap, să facem o recapitulare rapidă a acestor funcții de ordin superior și a scopurilor lor.

  1. funcția map(_:) aplică o închidere unei colecții de intrare și returnează colecția transformată
  2. funcția flatMap(_:) face același lucru și, de asemenea, aplatizează colecția rezultată
  3. funcția compactMap(_:) face același lucru cu map(_:) și elimină, de asemenea, nil din colecția rezultată

lucrul cu map(_:), flatMap(_:) și compactMap(_:) în abstract face uneori greu de imaginat cazurile lor de utilizare practică. Să discutăm de ce ai vrea să le folosești.

utilizarea unor funcții precum map (_:) pentru a aplica transformări secvențelor are câteva avantaje:

  • este mai concis decât utilizarea unei bucle for, deoarece nu aveți nevoie de variabile temporare și de un bloc cu mai multe linii for in { }.
  • de obicei, puteți scrie un apel la map(_:) pe o singură linie, ceea ce (de obicei) face codul dvs. mai lizibil.
  • funcții precum map(_:) pot fi înlănțuite, astfel încât să puteți aplica mai multe transformări la o secvență una câte una.

în general, funcțiile de ordin superior sunt utile deoarece vă permit să aplicați o funcție unei secvențe de valori. În loc să codificați transformarea procedural, puteți aplica funcția și puteți obține un rezultat înapoi.

cel mai practic caz de utilizare pentru flatMap(_:) este lucrul cu valori de intrare grupate sau imbricate, dar valoarea de ieșire dorită trebuie să fie unidimensională.

ai putea, într-o aplicație de muzică, de exemplu, au 3 matrice: melodii, artiști și liste de redare. Le combinați într-o singură matrice, apelați flatMap(_:) pe ea, selectați melodiile, artiștii și listele de redare pentru care isFavorite este true și ajungeți la o listă plată de articole care au fost favorizate.

un caz de utilizare practică pentru compactMap(_:)lucrează cu o transformare care poate reveni nil. Vă salvați câțiva pași triviali lăsând compactMap(_:) să filtreze imediat valorile nil. Un beneficiu suplimentar este compactMap(_:) de tip non-opțional de returnare; funcția filter(_:), în comparație, ar fi returnat o valoare opțională dacă ați filtrat nil.

puteți combina flatMap(_:) și compactMap(_:) și chiar filter(_:)sau reduce(_:_:). Imaginați-vă că construiți o aplicație de socializare. Doriți să construiți o cronologie a postărilor pentru un utilizator. Utilizați 3 interogări pentru a selecta ID-uri de postare pentru utilizator, de exemplu din postări de adepți, reclame și subiecte în tendințe.

  • puteți utiliza map(_:) pentru a extinde aceste ID-uri în obiecte reale Post
  • puteți utiliza flatMap(_:) pentru a aplatiza cele 3 grupuri într-o singură colecție
  • puteți utiliza compactMap(_:) pentru a elimina postările care nu au putut fi extinse

îngrijite!

angajați-vă ca dezvoltator iOS

Aflați cum să construiți Aplicații iOS 14 cu Swift 5

Înscrieți-vă la cursul meu de dezvoltare iOS și aflați cum să vă începeți cariera ca dezvoltator iOS profesionist.

lecturi suplimentare

merită să aflați despre map(_:), flatMap(_:) și compactMap(_:), deoarece acestea fac codul dvs. mai concis și mai lizibil. Puteți adăuga mai multe programe funcționale la codul aplicației. Odată ce te obișnuiești cu ei, nu-ți vine să crezi că ți-ai putea face munca fără ei.

mai ales diferențele dintre map(_:), flatMap(_:) și compactMap(_:) merită subliniate. Primul aplică o transformare într-o secvență, cea de-a doua aplatizează matricea rezultată, iar cea de-a treia elimină valorile nil înainte de a-și întoarce rezultatul. Minunat!

Lasă un răspuns

Adresa ta de email nu va fi publicată.