Menu
CoddyTech

Tùy chỉnh hàm bậc cao

Thuộc phần Logic và luồng thực thi trong hành trình Swift của Coddy. Bài học 42 trên 56.

Giờ đây, bạn có thể viết các hàm bậc cao (higher-order function) của riêng mình và chúng sẽ hoạt động ăn khớp với map và filter. Cấu trúc luôn giống nhau: nhận một closure làm tham số, gọi nó bên trong vòng lặp rồi trả về kết quả.

extension Array {
    func myMap<T>(_ transform: (Element) -> T) -> [T] {
        var result: [T] = []
        for item in self {
            result.append(transform(item))
        }
        return result
    }
}

[1, 2, 3].myMap { $0 * 10 }       // [10, 20, 30]

Nếu extension khiến bạn thấy hơi phức tạp, thay vào đó hãy viết một hàm độc lập, ý tưởng vẫn giống nhau:

func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
    var n = 0
    for item in items where predicate(item) {
        n += 1
    }
    return n
}

Khi đã có thể truyền các bao đóng, bạn sẽ không còn thấy thư viện chuẩn như phép màu nữa mà bắt đầu nhận ra đó là tập hợp những mẫu mà bạn có thể tự viết.

challenge icon

Thử thách

Trung bình

Viết một hàm tự do partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) duyệt qua mảng một lần và trả về một bộ giá trị (matched, rest): các phần tử thỏa mãn vị từ và các phần tử còn lại, cả hai đều giữ nguyên thứ tự ban đầu.

Đọc hai dòng: một số nguyên min, sau đó là danh sách các số nguyên được phân tách bằng dấu phẩy. Dùng partition với vị từ kiểm tra n > min. In ra:

  1. matched: <...>
  2. rest: <...>

Nối từng danh sách bằng , (hoặc để trống nếu không có gì để in).

Với đầu vào 5 / 2,7,3,8,5, đầu ra là:

matched: 7,8
rest: 2,3,5

Tự làm thử

let min = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }

// TODO: partition(_:by:) -> ([Int], [Int]); in ra các phần tử khớp và phần còn lại
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng thực thi

Tự luyện tập: Playground Swift