Harita, FlatMap ve CompactMap

Ş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 fortü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:

Ş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 fortü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:
Ş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 fortü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:

İ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 – mapflatMapve compactMap. Nasıl çalıştıklarına bir bakalım.

Diyelim ki #hashtagsbir 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 fortü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, Arrayher 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 fordö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ı mapyapalım – ve işimiz bitti!

mapYeni hashtagsfonksiyonumuz gibi kendimiz yazdığımız herhangi bir kod ile de kullanabiliriz . İşte mapbir 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 – hashtagsfonksiyonumuz bir Stringgiriş olarak kabul ettiğinden , tıpkı mapyukarıdan geçtiğimiz kapanış gibi – hashtagsfonksiyonumuzu doğrudan doğrudan bir argüman olarak geçebiliriz mapve 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 flatMapgiriyor. 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 flatMapaynı ş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 compactMapatmamıza izin veren var nil. Örneğin, sayıları içerebilen ve tüm bu sayıları uygun Intdeğ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 compactMapbu 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 Intbaşlatıcı bir Stringargü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 mapflatMapve 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 Stringdö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 mapiş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.

Comments

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

GIPHY App Key not set. Please check settings

2 Comments

  1. Greetings I am so delighted I found your blog
    page, I really found you by mistake, while I was researching
    on Bing for something else, Anyways I am here now and would just like to say cheers for a remarkable post and a all round interesting
    blog (I also love the theme/design), I don’t have time to read through it all at the moment but I have bookmarked it and also included
    your RSS feeds, so when I have time I will be back to read a lot more, Please do keep up the great work.

Yükleniyor…

0

Ne düşünüyorsun?

521 Points
Upvote Downvote

Yazar Cem Y.

Bir kod parçasının zaman karmaşıklığını ölçmek, yürütme süresi açısından maliyetlerini tahmin ederek algoritmaları ve diğer işlev türlerini optimize etmek için kullanılan yaygın bir tekniktir.

Zaman Karmaşıklığı | Swift

Spotify Kids.