scris de Reinder de Vries pe 12 iulie 2020 în dezvoltarea aplicațiilor, 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:
- cum
map(_:)
transformă o colecție sau o secvență prin aplicarea unei închideri - cum
flatMap(_:)
poate aplatiza o matrice de intrare, după apelareamap(_:)
- 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.
- utilizarea funcției Map în Swift
- utilizarea funcției FlatMap
- utilizarea funcției CompactMap
- de ce să folosiți FlatMap și CompactMap?
- 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ă rezultat = numere.hartă({ $0 * $0 })
imprimare (rezultat)
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ă rezultat = numere.flatMap ({ $0})
imprimare (rezultat)
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ă cel mai înalt = girafe.flatMap ({ $0.filtru({ $0 > 10 }) })
print (cel mai înalt)
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ă rezultat = numere.compactMap ({int ($0)})
imprimare (rezultat)
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 result
este . 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.
- funcția
map(_:)
aplică o închidere unei colecții de intrare și returnează colecția transformată - funcția
flatMap(_:)
face același lucru și, de asemenea, aplatizează colecția rezultată - funcția
compactMap(_:)
face același lucru cumap(_:)
ș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 liniifor 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 realePost
- 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!