- Published on
Swiftda KeyPath
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
KeyPath β Swift da property ga "yo'l" ko'rsatuvchi maxsus tur. Oddiy closure { $0.ism } yozish o'rniga \.ism deyish mumkin. Bu kodni qisqartiradi va ifodali qiladi. KeyPath funksiya sifatida ham ishlatilishi mumkin (Swift 5.2+) β map(\.ism) kabi.
KeyPath turlari: KeyPath<Root, Value> β faqat o'qish, WritableKeyPath<Root, Value> β o'qish va yozish (var property lar uchun), ReferenceWritableKeyPath β class ning var property siga yozish.
KeyPath asoslari
KeyPath yaratish uchun \Tur.property formatida yoziladi. Qiymat olish uchun ob'ekt[keyPath: \.property] ishlatiladi. let property ga yozib bo'lmaydi, faqat var property ga WritableKeyPath orqali yozish mumkin.
struct Talaba {
let ism: String
var baho: Int
let guruh: String
}
// βββββββββββββββββββββββββββββββββββββββ
// KEYPATH YARATISH
// βββββββββββββββββββββββββββββββββββββββ
// \Talaba.ism β Talaba turidagi ism property siga yo'l
let ismKeyPath: KeyPath<Talaba, String> = \Talaba.ism
let bahoKeyPath: WritableKeyPath<Talaba, Int> = \Talaba.baho
let ali = Talaba(ism: "Ali", baho: 5, guruh: "A")
// KeyPath bilan qiymat olish
let ism = ali[keyPath: ismKeyPath] // "Ali"
let ism2 = ali[keyPath: \.ism] // "Ali" β qisqa yozuv
// βββββββββββββββββββββββββββββββββββββββ
// WRITABLEKEYPATH β yozish mumkin
// βββββββββββββββββββββββββββββββββββββββ
var vali = Talaba(ism: "Vali", baho: 3, guruh: "B")
vali[keyPath: \.baho] = 5 // var property ga yozish β
// vali[keyPath: \.ism] = "X" // β let β yozib bo'lmaydi
KeyPath va Higher-Order Functions
KeyPath ning eng kuchli tomoni β map, sorted, max kabi funksiyalar bilan birgalikda ishlatilishi. talabalar.map(\.ism) β talabalar.map { $0.ism } bilan bir xil, lekin ancha qisqa va o'qish oson.
let talabalar = [
Talaba(ism: "Ali", baho: 5, guruh: "A"),
Talaba(ism: "Vali", baho: 3, guruh: "B"),
Talaba(ism: "Gani", baho: 4, guruh: "A"),
Talaba(ism: "Doni", baho: 5, guruh: "B"),
]
// βββββββββββββββββββββββββββββββββββββββ
// MAP BILAN KEYPATH
// βββββββββββββββββββββββββββββββββββββββ
// Eski usul:
let ismlar1 = talabalar.map { $0.ism }
// KeyPath bilan β qisqa va ifodali:
let ismlar2 = talabalar.map(\.ism)
// ["Ali", "Vali", "Gani", "Doni"]
let baholar = talabalar.map(\.baho)
// [5, 3, 4, 5]
// βββββββββββββββββββββββββββββββββββββββ
// FILTER BILAN KEYPATH
// βββββββββββββββββββββββββββββββββββββββ
// KeyPath ni predicate sifatida (extension kerak):
let yuqoriBaholar = talabalar.filter { $0.baho >= 4 }
// sorted bilan
let tartiblangan = talabalar.sorted { $0.baho < $1.baho }
// βββββββββββββββββββββββββββββββββββββββ
// MIN/MAX BILAN KEYPATH
// βββββββββββββββββββββββββββββββββββββββ
let engYuqori = talabalar.max { $0.baho < $1.baho }
print(engYuqori?.ism ?? "") // "Ali" yoki "Doni"
KeyPath bilan amaliy misollar
KeyPath ning chinakam kuchi generik funksiyalar bilan namoyon bo'ladi. Masalan, istalgan property bo'yicha guruhlash funksiyasi yozish mumkin β bir safar yozib, har xil property lar bilan ishlatish. extension bilan massivga yangi metodlar qo'shish ham mumkin.
// βββββββββββββββββββββββββββββββββββββββ
// GENERIK FUNKSIYA β KeyPath bilan
// βββββββββββββββββββββββββββββββββββββββ
// Istalgan property bo'yicha guruhlash
func guruhla<T, K: Hashable>(
_ massiv: [T],
boyicha keyPath: KeyPath<T, K>
) -> [K: [T]] {
Dictionary(grouping: massiv) { $0[keyPath: keyPath] }
}
let guruhlar = guruhla(talabalar, boyicha: \.guruh)
// ["A": [Ali, Gani], "B": [Vali, Doni]]
let bahoBoyicha = guruhla(talabalar, boyicha: \.baho)
// [5: [Ali, Doni], 3: [Vali], 4: [Gani]]
// βββββββββββββββββββββββββββββββββββββββ
// YIGINDI β KeyPath bilan
// βββββββββββββββββββββββββββββββββββββββ
extension Sequence {
func yigindi<T: Numeric>(of keyPath: KeyPath<Element, T>) -> T {
reduce(.zero) { $0 + $1[keyPath: keyPath] }
}
}
let umumiyBaho = talabalar.yigindi(of: \.baho) // 17
π― Topshiriq
Mahsulot struct yarating (nomi, narxi, kategoriya). map(\.nomi) bilan nomlar ro'yxatini oling. guruhla(_:boyicha:) funksiyasini ishlatib kategoriya bo'yicha guruhlang. yigindi(of:) extension bilan umumiy narxni hisoblang.