Let's think about it this way
In Part 1, we got as far as creating the task list and adding tasks. In this part, we'll use Kotlin's collection functions — filter, find, forEach — along with lambda expressions to add search/filter/status-update features to the task list. A higher-order function is a function that can accept another function as a parameter, so the caller can pass in custom filter logic as a lambda. We'll use a when expression to make task status changes more readable, and combine it with the safe call operator for null safety, so a missing task doesn't trigger an error.
Let's build it
Add 3 more functions to the TaskManager class — completeTask(id: Int) finds the task with tasks.find { it.id == id }, sets isDone = true, and shows "Task not found" if no task matches. filterByPriority(priority: Priority) uses a filter lambda to return the task list by priority. Write a higher-order function searchTasks(predicate: (Task) -> Boolean) that lets the caller pass a custom condition (e.g. title contains a keyword) as a lambda. In main(), try completing a task, filtering for just HIGH priority tasks, then call searchTasks with a lambda like title.contains("Kotlin").
Code Example
class TaskManager {
private val tasks = mutableListOf<Task>()
fun addTask(title: String, priority: Priority) {
if (title.isBlank()) return
tasks.add(Task(id = tasks.size + 1, title = title, priority = priority))
}
fun completeTask(id: Int) {
val task = tasks.find { it.id == id }
if (task != null) {
task.isDone = true
println("Task #${task.id} completed: ${task.title}")
} else {
println("Task not found: #$id")
}
}
fun filterByPriority(priority: Priority): List<Task> =
tasks.filter { it.priority == priority }
fun searchTasks(predicate: (Task) -> Boolean): List<Task> =
tasks.filter(predicate)
fun printAll() = tasks.forEach { println("#${it.id} - ${it.title} (${it.priority}) done=${it.isDone}") }
}
fun main() {
val manager = TaskManager()
manager.addTask("Kotlin syntax ပြန်ကြည့်ရန်", Priority.HIGH)
manager.addTask("Data class ကျင့်ရန်", Priority.MEDIUM)
manager.addTask("Lambda ကျင့်ရန်", Priority.HIGH)
manager.completeTask(1)
println("--- HIGH priority tasks ---")
manager.filterByPriority(Priority.HIGH).forEach { println(it.title) }
println("--- Search 'Kotlin' ---")
manager.searchTasks { it.title.contains("Kotlin") }.forEach { println(it.title) }
}You'll see a message confirming Task #1 was completed, along with a list of two HIGH priority tasks and one task containing 'Kotlin'.5-Minute Challenge
Practice writing a new function called pendingTasks() that returns only the tasks where isDone == false, using a filter { } lambda.
A Quick Warning
When designing a higher-order function, specifying the predicate function's parameter type explicitly lets Kotlin's type inference auto-detect the lambda parameter type on the caller's side, making the code shorter.