Let's think about this for a second
In this part, we'll add the core features — task completion, filtering, sorting — to the TaskManager we built in Part 1. We'll write a method that accepts a closure as a parameter and filters the task list by a custom condition, which is practice for the higher-order function pattern. We'll use sorted(by:) with a custom comparator closure to sort by priority. We'll write the pending task count as a computed property so it needs no get/set logic, reinforcing the properties topic. By the end of this stage, the app becomes a tool that does practical operations, not just holds data.
Let's build it
Write a completeTask(id: Int) method that sets isDone to true on the task with the matching id (find the array index with firstIndex(where:)). Write a filter(by condition: (Task) -> Bool) -> [Task] method that filters the task array using a closure condition. Write a tasks(sortedBy:) method that returns the array sorted from high to low priority. Add a var pendingCount: Int computed property that returns the count of tasks where isDone == false. Update printAllTasks() to print in sortedBy priority order.
Sample Code
extension TaskManager {
func completeTask(id: Int) {
if let index = tasks.firstIndex(where: { $0.id == id }) {
tasks[index].isDone = true
}
}
func filter(by condition: (Task) -> Bool) -> [Task] {
return tasks.filter(condition)
}
func tasksSortedByPriority() -> [Task] {
let order: [Priority] = [.high, .medium, .low]
return tasks.sorted {
order.firstIndex(of: $0.priority)! < order.firstIndex(of: $1.priority)!
}
}
var pendingCount: Int {
return tasks.filter { !$0.isDone }.count
}
}
manager.completeTask(id: 1)
let highPriorityTasks = manager.filter { $0.priority == .high }
print("High priority pending: \(highPriorityTasks.count)")
print("Total pending: \(manager.pendingCount)")After calling completeTask, pendingCount drops by one, and the high-priority filter result also prints the correct array.Give it 5 minutes
Write a line yourself that filters out only the tasks where isDone == true, and add a computed property called completedCount. Spend about 5 minutes on it.
One thing to watch out for
Since array elements are the Task value type, you need to mutate them directly by index, like tasks[index].isDone = true — changing the local copy inside a for task in tasks loop won't change the original array.