Completing tasks
- Kotlin course
- Beginner
- Lesson 86/116
- 6 min
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 runThis "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.
Practice 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().
Starter code
fun main() {
val list = TodoList()
list.addTask("Shopping")
list.addTask("Homework")
// Complete "Homework" and print with listTasks
}
// The Task and TodoList classes stay as defined in the previous lesson.
// Add the completeTask method inside TodoList: find with indexOfFirst, update with copy.Sample 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)
}
}
}Expected output
[ ] Shopping [x] Homework
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Match expression to role
| Term | Meaning |
|---|---|
completeTask(title) |
Completes the task |
indexOfFirst { } |
Index of first match |
copy(done = true) |
New copy, done = true |
tasks[i] = ... |
List slot is updated |
2 How does completeTask update a task?
- Builds a new list
- Makes a new Task with copy and replaces it Correct answer
- Deletes the old Task
- Sets the Task to null
Explanation: Since Task is immutable, we make a copy with copy and replace it.
3 Fill in the blank: update with copy
tasks[i] = tasks[i].____(done = true)
tasks[i] = tasks[i].copy(done = true)
Explanation: tasks[i].copy(done = true) makes a new copy.