Kotlin
Completing tasks
Learn to update task status with completeTask.
Completing tasks: completeTask and copy
To complete a task, the completeTask(title) method finds the task whose title matches and sets done to true. Because Task is a data class (immutable), we use copy(done = true) to make an updated copy and replace the slot in the list.
fun completeTask(title: String) {
val i = tasks.indexOfFirst { it.title == title }
if (i >= 0) {
tasks[i] = tasks[i].copy(done = true)
}
}
indexOfFirst { } gives the first index matching the condition, or -1. The i >= 0 check makes the update happen only if the task was found.
indexOfFirst and a missing task
indexOfFirst { condition } returns the index of the first element matching the condition; if none matches, it returns -1. This lets completeTask silently do nothing when called with a non-existent title.
val i = tasks.indexOfFirst { it.title == "Missing" }
// i = -1; the if (i >= 0) block does not run
This "silently skip" approach keeps the CLI from crashing when the user mistypes a title. You can also add a "task not found" message if you prefer.
Exercise Add and call the completeTask method
Add a fun completeTask(title: String) method to TodoList: find with val i = tasks.indexOfFirst { it.title == title }, and inside if (i >= 0) do tasks[i] = tasks[i].copy(done = true). In main add two tasks, call completeTask("Homework"), and print with listTasks().
Show example solution
fun main() {
val list = TodoList()
list.addTask("Shopping")
list.addTask("Homework")
list.completeTask("Homework")
list.listTasks()
}
data class Task(val title: String, val done: Boolean = false) {
fun format() = if (done) "[x] $title" else "[ ] $title"
}
class TodoList {
val tasks = mutableListOf<Task>()
fun addTask(title: String) {
tasks.add(Task(title))
}
fun listTasks() {
tasks.forEach { println(it.format()) }
}
fun completeTask(title: String) {
val i = tasks.indexOfFirst { it.title == title }
if (i >= 0) {
tasks[i] = tasks[i].copy(done = true)
}
}
}
Test yourself
-
Match expression to role
- completeTask(title)
- Completes the task
- indexOfFirst { }
- Index of first match
- copy(done = true)
- New copy, done = true
- tasks[i] = ...
- List slot is updated
-
How does completeTask update a task?
- Builds a new list
- Makes a new Task with copy and replaces it
- Deletes the old Task
- Sets the Task to null
Show answer
Makes a new Task with copy and replaces it — Since Task is immutable, we make a copy with copy and replace it.
-
Fill in the blank: update with copy
tasks[i] = tasks[i].____(done = true)
Show answer
tasks[i] = tasks[i].copy(done = true)
Next lesson: Putting it together