เริ่มจากโมเดลกันก่อน
ให้เราสร้างไฟล์ใหม่ ด้วยการคลิ๊กขวาที่โฟลเดอร์ TodoApp ใน Project navigator เลือก New File...
จากนั้นเลือก Swift File กด Next
ตั้งชื่อไฟล์เป็น Todo แล้วกด create
Xcode จะแสดงไฟล์ที่เพิ่งสร้างให้เรา
Todo.swift
ให้เราเขียนโค้ดดังนี้
import Foundation
class Todo {
private var items = [TodoItem]()
var totalItems: Int {
return items.count
}
func item(at index: Int) -> TodoItem {
return items[index]
}
func add(item: TodoItem) {
items.insert(item, at: 0)
}
func remove(at index: Int) {
items.remove(at: index)
}
func index(of item: TodoItem) -> Int? {
return items.index(where: { (todoItem) -> Bool in
return todoItem === item
})
}
func move(from sourceIndex: Int, to destinationIndex: Int) {
let item = items.remove(at: sourceIndex)
items.insert(item, at: destinationIndex)
}
}
class TodoItem {
var title: String
var isDone: Bool
init(title: String, isDone: Bool) {
self.title = title
self.isDone = isDone
}
func toggleIsDone() {
self.isDone = !self.isDone
}
}
บรรทัดที่ 3 - 27 เป็นการประกาศ Class Todo ที่เก็บรวบรวม TodoItem
บรรทัดที่ 29 - 41 เป็น Class TodoItem
บรรทัดที่ 6 - 8 เรียกว่า compute property สามารถ get ค่าได้อย่างเดียวไม่สามารถ set ค่าได้เนื่องจากไม่สามารถเก็บค่าไว้ได้ โดยเมื่อเรียกจะได้จำนวน TodoItem ที่เก็บไว้ใน items กลับไป
บรรทัดที่ 10 - 12 เป็นการประกาศฟังก์ชั่นที่รับ Int และคืนเป็น TodoItem ใช้ในการ get TodoItem ที่เก็บไว้ใน items ตาม index ที่ระบุ
บรรทัดที่ 14 - 16 เป็นการประกาศฟังก์ชั่นที่รับ TodoItem ใช้ในการเก็บ TodoItem เพิ่ม โดยเพิ่มลงไปใน index ที่ 0 ของ items (Prepend)
บรรทัดที่ 18 - 20 เป็นการประกาศฟังก์ชั่นที่ใช้ลบ TodoItem ตาม index ที่ระบุ
บรรทัดที่ 22 - 26 เป็นการประกาศฟังก์ชั่นที่ใช้ในการหา index ของ TodoItem ที่อยู่ใน items
TodoItem.swift
เนื่องจาก Todo.swift มีคลาส TodoItem ปนอยู่ด้วยจะเป็นการดีกว่าที่เราจะแยกมันออกมาเป็นอีกไฟล์นึงแทน ให้เราสร้างไฟล์ใหม่ชื่อ TodoItem.swift
แล้วย้ายโค้ดมาที่นี่
import Foundation
class TodoItem {
var title: String
var isDone: Bool
init(title: String, isDone: Bool) {
self.title = title
self.isDone = isDone
}
func toggleIsDone() {
self.isDone = !self.isDone
}
}
ฟังก์ชั่นใน Swift (เพิ่มเติม)
// การประกาศฟังก์ชั่น
func functionName(externalLabel internalLabel: Type) -> Type {
// external label จะเอาไว้ใช้ตอนเรียกฟังก์ชั่น
// internal label จะเอาไว้ใช้ในฟังก์ชั่น
// external และ internal เป็นอันเดียวกันได้โดยเขียนอันเดียว
// type เป็น swift data type เช่น String, Int อื่น ๆ
return internalLabel
}
// เวลาเรียกใช้งาน
let a = functionName(externalLabel: ค่า)
// หลายครั้งเราจะเห็นฟังก์ชั่นแบบ
func index(of item: TodoItem) -> Int? {
return items.index(where: { (todoItem) -> Bool in
return todoItem === item
})
}
/*
เราจะเรียกฟังก์ชั่นที่ไม่มีชื่อว่า Closure
{ (todoItem) -> Bool in
return todoItem === item
}
*/
การลดรูปฟังก์ชั่นใน Swift
func index(of item: TodoItem) -> Int? {
return items.index(where: { (todoItem) -> Bool in
return todoItem === item
})
}
จากโค้ดนี้ในบรรทัดที่ 2 - 4 สามารถลดรูปได้แบบนี้
ตัด return ออก เนื่องจากมีโค้ดบรรทัดเดียว ผลลัพธ์บรรทัดนั้นจึงเป็นผลลัพธ์ของฟังก์ชัน
items.index(where: { (todoItem) -> Bool in
todoItem === item
})
ตัด -> Bool ออก เนื่องจากเรารู้จากฟังก์ชั่น index แล้วว่าต้องรับ ฟังก์ชั่นที่ return Bool
items.index(where: { (todoItem) in
todoItem === item
})
ตัด (todoItem) in ออกแทนที่ parameter แรกที่รับ ด้วย $0
items.index(where: { $0 === item })
ตัด (where: ) ออก parameter สุดท้ายถ้าเป็นฟังก์ชั่น สามารถละได้
items.index { $0 === item }