İlk başta görünmeyebilir, ancak uygulama geliştiricileri olarak yazdığımız kodların çoğu verileri ve değerleri farklı şekil ve biçimlere dönüştürmekle ilgilidir. Örneğin, bir ağ isteği gerçekleştirerek bir URL’yi bir veri parçasına dönüştürebilir ve ardından bu verileri daha sonra listeye dayalı bir UI’ye dönüştürdüğümüz bir dizi diziye dönüştürebiliriz.
Bu değer dönüşümleri gerçekleştirmek bir yolu tarafından haritalama bir dönüşümü kullanılarak, yeni değerler bir diziye bir dizi değere. Swift standart kütüphanesi bu tür haritalama için üç ana API sunar – map
, flatMap
ve compactMap
. Nasıl çalıştıklarına bir bakalım.
Diyelim ki #hashtags
bir dizgede görünen herhangi bir şeyi, dizgiyi kelimelere bölerek ve sonra da bu #
karakterleri filtreleyerek, sadece karakteriyle başlayan karakter dizilerini içerecek şekilde yazdığımızı varsayalım :
func hashtags(in string: String) -> [String] {
let words = string.components(
separatedBy: .whitespacesAndNewlines
)
// Filtre, belirli bir gereksinime uymayan öğeleri kaldırmamıza olanak tanır, bu durumda öncü bir karma karakterle başlamayanları:
return words.filter { $0.starts(with: "#") }
}
Yukarıdaki işlevi çağırmak daha sonra şuna benzer:
let tags = hashtags(in: "#Swift by Sundell #Basics")
print(tags) // ["#Swift", "#Basics"]
Şimdi, fonksiyonumuzun ürettiği hashtagleri normalleştirmek istediğimizi varsayalım, böylece her zaman küçük harflerle gösterilirler. Bunu yapmanın bir yolu, yeni bir dizi oluşturmak, ardından for
tüm etiketleri yinelemek için bir döngü kullanmak ve ardından her bir etiketin daha küçük bir sürümünü o yeni diziye eklemek olacaktır:
var lowercasedTags = [String]()
for tag in tags {
lowercasedTags.append(tag.lowercased())
}
Bununla birlikte, esasen yukarıda yaptığımız şey map
, (bir dizi değere çağrıldığında, Array
her bir elemana kapanış temelli bir dönüşüm uygulamamıza izin veren) bir el ile uygulamasının yazılmasıdır. bunun yerine:
func hashtags(in string: String) -> [String] {
let words = string.components(
separatedBy: .whitespacesAndNewlines
)
let tags = words.filter { $0.starts(with: "#") }
// Using 'map' we can convert a sequence of values into
// a new array of values, using a closure as a transform:
return tags.map { $0.lowercased() }
}
Çok daha iyi! Şimdi artık kendi for
döngümüzü sürdürmek zorunda değiliz, ne de geçici bir dizi oluşturmak zorunda değiliz, sadece basit bir çağrı map
yapalım – ve işimiz bitti!
map
Yeni hashtags
fonksiyonumuz gibi kendimiz yazdığımız herhangi bir kod ile de kullanabiliriz . İşte map
bir dizi diziyi bir dizi karma diziye dönüştürmek için nasıl kullanabileceğimizi – hepsi bir arada:
let strings = [
"I'm excited about #SwiftUI",
"#Combine looks cool too",
"This year's #WWDC was amazing"
]
let tags = strings.map { hashtags(in: $0) }
print(tags) // [["#swiftui"], ["#combine"], ["#wwdc"]]
Daha da iyisi – hashtags
fonksiyonumuz bir String
giriş olarak kabul ettiğinden , tıpkı map
yukarıdan geçtiğimiz kapanış gibi – hashtags
fonksiyonumuzu doğrudan doğrudan bir argüman olarak geçebiliriz map
ve aslında bu fonksiyonu dönüşüm kapanışı olarak kullanır:
let tags = strings.map(hashtags)
Oldukça havalı! Bununla birlikte, yukarıda elde ettiğimiz çıktı [[String]]
, muhtemelen istediğimiz şey olmayan dizgelerin (veya ) dizilerini içeren bir dizidir . Büyük olasılıkla , iç içe geçmiş diziler (veya ) olmadan yalnızca etiket içeren bir “düz” dizi istiyoruz [String]
.
Burası içeriye flatMap
giriyor. Sadece harita gibi çalışıyor, fakat sonuçta ortaya çıkan “dizi dizisini” tek bir dizide düzleştiriyor – şunun gibi:
let tags = strings.flatMap(hashtags)
print(tags) // ["#swiftui", "#combine", "#wwdc"]
Dolayısıyla map
, bir değerler dizisini başka değerler dizisine dönüştürür ve flatMap
aynı şeyi yapar, ancak yuvalanmış koleksiyonların sonuçlarını yalnızca tek bir diziye yassılaştırır.
Son olarak, dönüşümümüzün üretebileceği değerleri compactMap
atmamıza izin veren var nil
. Örneğin, sayıları içerebilen ve tüm bu sayıları uygun Int
değerlere dönüştürmek istediğimizi belirten bir dizi dizimiz olduğunu varsayalım. Bu başarısız olabilecek (ve dolayısıyla üretecek nil
) bir işlemdir , bu yüzden compactMap
bu dönüşümü gerçekleştirmek için kullanacağız ve bize yalnızca aradığımız geçerli tamsayıları vereceğiz:
let numbers = ["42", "19", "notANumber"]
let ints = numbers.compactMap { Int($0) }
print(ints) // [42, 19]
Tıpkı daha önce olduğu gibi, kullandığımız Int
başlatıcı bir String
argüman kabul ettiğinden ve bir dizi dizginin eşlemesini yaptığımız için – Int.init
çağırırken doğrudan dönüşümümüzden doğrudan geçebiliriz compactMap
:
let ints = numbers.compactMap(Int.init)
Yani map
, flatMap
ve compactMap
– ve bu gibi koleksiyonlara nasıl uygulanabilecekleri Array
. Ancak Swift’deki değerleri haritalandırmanın tek yolu bu değil. Aslında, haritalama, dizileri dönüştürmekten çok daha fazla durumda uygulanabilen çok daha genel bir kavramdır.
Örneğin, yukarıdaki haritalama işlevlerini isteğe bağlı seçeneklerde de kullanabiliriz, örneğin bir isteğe bağlı seçeneği isteğe bağlı bir seçeneğe String
dönüştürmek için Int
– yine daha Int
önce kullandığımız başlatıcıyı kullanarak :
func convertToInt(_ string: String?) -> Int? {
return string.flatMap(Int.init)
}
Ayrıca map
örneğin varsayılan olarak, isteğe bağlı olmayan bir değer üretmemizi gerektiren düz de kullanabiliriz :
func convertToInt(_ string: String?) -> Int? {
return string.map { Int($0) ?? 0 }
}
Swift’in çeşitli map
işlevleri, sekansları veya opsiyonları yeni bir forma dönüştürmemiz gerektiğinde akılda tutulması gereken harika fonksiyonlardır. Bunlar aynı zamanda Swift’e özgü olmayan genel kalıplardır ve her birinin nasıl çalıştığını öğrenmek, daha basit ve daha zarif bir kodla sonuçlanabilecek güçlü bir işlevsel programlama özellikleri grubunun kilidini açmamıza izin verebilir.
GIPHY App Key not set. Please check settings