การใช้ KeyPaths ในคอลเลกชัน
เรียงลำดับและแปลงคอลเลกชันตามเส้นทางคีย์
การใช้ KeyPaths ในคอลเลกชัน เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คีย์พาธโดดเด่นในคอลเลกชัน
การดำเนินการกับคอลเลกชัน เช่น map, sorted และ filter มักทำเพียง read คุณสมบัติหนึ่งรายการของแต่ละองค์ประกอบ คีย์พาธช่วยให้คุณสื่อเจตนานั้นได้โดยไม่ต้องเขียนคลอเชอร์
Swift ยอมรับคีย์พาธได้ทุกตำแหน่งที่คาดว่าจะเป็นฟังก์ชันซึ่งรับอาร์กิวเมนต์เดียวและคืนค่า เนื่องจากคีย์พาธสามารถใช้เป็นฟังก์ชันจาก Root ไปยัง Value ได้
struct Person {
let name: String
let age: Int
}
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let names = people.map(\.name)
print(names)map แบบย่อด้วยคีย์พาธ
การส่ง map(\.property) เทียบเท่ากับการเขียนคลอเชอร์ที่คืนค่าคุณสมบัตินั้น แต่สั้นและชัดเจนกว่า เครื่องหมายแบ็กสแลชนำหน้าและจุดช่วยให้คอมไพเลอร์อนุมานชนิดขององค์ประกอบได้
ลองเปรียบเทียบสองรูปแบบด้านล่าง ทั้งสองรูปแบบให้ผลลัพธ์เดียวกัน
struct Person {
let name: String
let age: Int
}
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let closureForm = people.map { $0.age }
let keyPathForm = people.map(\.age)
print(closureForm)
print(keyPathForm)sorted(by:) พร้อมการเปรียบเทียบด้วยคีย์พาธ
หากต้องการเรียงลำดับตามคุณสมบัติ คุณยังคงต้องเขียนคลอเชอร์เปรียบเทียบขนาดเล็ก แต่สามารถอ่านคุณสมบัติผ่านคีย์พาธภายในคลอเชอร์เพื่อให้โค้ดชัดเจนขึ้น
ที่นี่เราเรียงผู้คนจากอายุน้อยไปมากโดยเปรียบเทียบค่า age ของแต่ละคน
struct Person {
let name: String
let age: Int
}
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let path = \Person.age
let sorted = people.sorted { $0[keyPath: path] < $1[keyPath: path] }
print(sorted.map(\.name))ตัวช่วยเรียงลำดับที่นำกลับมาใช้ใหม่ได้
คุณสามารถเขียนตัวช่วยทั่วไปที่เรียงอาร์เรย์ใดก็ได้ตามคุณสมบัติที่เปรียบเทียบได้ โดยรับคุณสมบัตินั้นเป็นอาร์กิวเมนต์คีย์พาธ วิธีนี้ทำให้การเรียงลำดับตามช่องข้อมูลกลายเป็นคำสั่งบรรทัดเดียวที่ใช้ซ้ำได้ทั่วทั้งโค้ดของคุณ
ข้อจำกัด T: Comparable รับรองว่าคุณสมบัตินั้นสามารถนำมาเรียงลำดับได้
func sorted<E, T: Comparable>(_ array: [E], by path: KeyPath<E, T>) -> [E] {
array.sorted { $0[keyPath: path] < $1[keyPath: path] }
}
struct Person { let name: String; let age: Int }
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
print(sorted(people, by: \.age).map(\.name))การกรองผ่านคีย์พาธ
สำหรับ filter คุณต้องใช้เงื่อนไขตรวจสอบที่คืนค่าเป็น Bool ดังนั้นคีย์พาธของคุณสมบัติแบบเดี่ยวจะใช้ได้โดยตรงก็ต่อเมื่อคุณสมบัตินั้นเป็น Bool อยู่แล้ว
ที่นี่แต่ละงานมีแฟล็ก isDone และเรากรองข้อมูลโดยใช้รูปแบบคีย์พาธแบบย่อ
struct Task {
let title: String
let isDone: Bool
}
let tasks = [Task(title: "A", isDone: true), Task(title: "B", isDone: false)]
let finished = tasks.filter(\.isDone)
print(finished.map(\.title))การกรองตามคุณสมบัติที่ไม่ใช่บูลีน
เมื่อกรองตามคุณสมบัติที่ไม่ใช่บูลีน ให้ read คุณสมบัตินั้นผ่านคีย์พาธภายในคลอเชอร์แล้วนำมาเปรียบเทียบ ตัวช่วยทั่วไปสามารถเก็บรูปแบบนี้ไว้ใช้กับคุณสมบัติใดก็ได้ที่เปรียบเทียบความเท่ากันได้
ที่นี่เราเก็บไว้เฉพาะ people ที่มี city ตรงกับค่าเป้าหมาย
struct Person { let name: String; let city: String }
func filter<E, T: Equatable>(_ array: [E], _ path: KeyPath<E, T>, equals value: T) -> [E] {
array.filter { $0[keyPath: path] == value }
}
let people = [Person(name: "Ana", city: "Oslo"), Person(name: "Ben", city: "Rome")]
print(filter(people, \.city, equals: "Oslo").map(\.name))max และ min ตามคีย์พาธ
เมธอด max(by:) และ min(by:) รับคลอเชอร์เปรียบเทียบเช่นเดียวกับ sorted ให้ read คุณสมบัติผ่านคีย์พาธเพื่อค้นหาองค์ประกอบที่มีค่ามากที่สุดหรือน้อยที่สุด
ที่นี่เราค้นหาบุคคลที่เป็น oldest
struct Person { let name: String; let age: Int }
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25), Person(name: "Cy", age: 41)]
let path = \Person.age
if let oldest = people.max(by: { $0[keyPath: path] < $1[keyPath: path] }) {
print(oldest.name)
}การรวมค่าคุณสมบัติด้วย reduce
คุณสามารถใช้ map(\.property) ร่วมกับ reduce เพื่อรวมค่าช่องข้อมูลตัวเลข เริ่มจากดึงค่าของแต่ละองค์ประกอบให้เหลือเป็นตัวเลขที่ต้องการ แล้วจึงนำมาบวกกัน
ที่นี่เรารวมอายุทั้งหมดในกระบวนการต่อเนื่องเดียว
struct Person { let name: String; let age: Int }
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let totalAge = people.map(\.age).reduce(0, +)
print(totalAge)การจัดกลุ่มตามคีย์พาธ
Dictionary(grouping:by:) จัดองค์ประกอบลงกลุ่มตามผลลัพธ์ของคลอเชอร์ ให้ read คุณสมบัติผ่านคีย์พาธเพื่อจัดกลุ่มตามช่องข้อมูลนั้น
ที่นี่ people จะถูกจัดกลุ่มตาม city ลงในพจนานุกรมที่มีค่าเป็นอาร์เรย์
struct Person { let name: String; let city: String }
let people = [
Person(name: "Ana", city: "Oslo"),
Person(name: "Ben", city: "Rome"),
Person(name: "Cy", city: "Oslo")
]
let path = \Person.city
let byCity = Dictionary(grouping: people, by: { $0[keyPath: path] })
print(byCity["Oslo"]?.map(\.name) ?? [])การเรียงลำดับหลายช่องข้อมูล
หากต้องการเรียงตามช่องข้อมูลหนึ่งและใช้ช่องข้อมูลอื่นตัดสินเมื่อค่าเท่ากัน ให้เปรียบเทียบคีย์พาธหลักก่อน แล้วใช้คีย์พาธรองเป็น fallback เมื่อค่าหลักเท่ากัน
ที่นี่เราเรียงตาม age แล้วเรียงตามชื่อเมื่อ age เท่ากัน
struct Person { let name: String; let age: Int }
let people = [
Person(name: "Zoe", age: 30),
Person(name: "Ana", age: 30),
Person(name: "Ben", age: 25)
]
let sorted = people.sorted {
if $0[keyPath: \Person.age] != $1[keyPath: \Person.age] {
return $0.age < $1.age
}
return $0.name < $1.name
}
print(sorted.map(\.name))เหตุใดคีย์พาธจึงดีกว่าคลอเชอร์ในกรณีนี้
การใช้คีย์พาธในคำสั่งของคอลเลกชันช่วยลดโค้ดประกอบที่ซ้ำซ้อน ลดโอกาสพิมพ์ผิดในตัวคลอเชอร์ และทำให้เจตนาชัดเจนว่าคุณกำลังดึงข้อมูลจากช่องข้อมูลเพียงรายการเดียว
สำหรับการแปลงข้อมูลที่ซับซ้อน คลอเชอร์ยังคงเป็นเครื่องมือที่เหมาะสม แต่สำหรับการ read คุณสมบัติโดยตรง \.property เป็นตัวเลือกที่ชัดเจนที่สุด
struct Product { let name: String; let price: Double }
let products = [Product(name: "Pen", price: 2), Product(name: "Pad", price: 5)]
let names = products.map(\.name)
let prices = products.map(\.price)
print(names)
print(prices)ตรวจสอบด่วน: คีย์พาธใน map
เลือกรูปแบบคีย์พาธแบบกระชับสำหรับดึงคุณสมบัติหนึ่งรายการจากแต่ละองค์ประกอบ
ทบทวน: คีย์พาธในคอลเลกชัน
คุณได้เห็นแล้วว่าคีย์พาธช่วยทำให้โค้ดคอลเลกชันกระชับขึ้นได้อย่างไร:
map(\.property)ดึงค่าจากช่องข้อมูลหนึ่งรายการโดยไม่ต้องใช้คลอเชอร์filter(\.boolProperty)ใช้ได้โดยตรงกับช่องข้อมูลแบบ Bool ส่วนช่องข้อมูลชนิดอื่นให้ใช้คลอเชอร์ร่วมกับ[keyPath:]- การเรียงลำดับ
maxและminจะ read คุณสมบัติผ่านคีย์พาธภายในคลอเชอร์เปรียบเทียบ - ตัวช่วยทั่วไปที่รับ
KeyPathช่วยเปลี่ยนการเรียงลำดับและการกรองตามช่องข้อมูลให้เป็นคำสั่งบรรทัดเดียวที่นำกลับมาใช้ใหม่ได้
ถัดไปคุณจะเรียนรู้คีย์พาธแบบเขียนได้ ซึ่งช่วยให้คุณกำหนดค่าได้ ไม่ใช่แค่อ่านค่า
struct Person { let name: String; let age: Int }
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let youngestFirst = people.sorted { $0[keyPath: \Person.age] < $1[keyPath: \Person.age] }
print(youngestFirst.map(\.name))คำถามที่พบบ่อย
บทเรียน “การใช้ KeyPaths ในคอลเลกชัน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การใช้ KeyPaths ในคอลเลกชัน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การใช้ KeyPaths ในคอลเลกชัน”
เรียงลำดับและแปลงคอลเลกชันตามเส้นทางคีย์ คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การใช้ KeyPaths ในคอลเลกชัน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน KeyPath
- การใช้ KeyPaths ในคอลเลกชัน
- KeyPath ที่เขียนได้และอ้างอิงได้
- @dynamicMemberLookup