Removing a Task
Part of the Logic & Flow section of Coddy's GO journey — lesson 24 of 68.
Challenge
EasyIn this part of your task management system, you'll implement the ability to remove tasks from your list. This challenge focuses on slice manipulation using the append function to reconstruct a slice without a specific element, demonstrating how to permanently remove items from your data structure.
You will receive three inputs:
- A string representing the number of tasks (e.g.,
"4") - A string containing task data in the format:
"name1:status1,name2:status2,name3:status3"where status is either"true"or"false"(e.g.,"Buy groceries:false,Call dentist:true,Finish project:false,Review code:true") - A string representing the index of the task to remove (e.g.,
"1"for the second task, using 0-based indexing)
Your task is to:
- Define the same
Taskstruct from previous challenges withName(string) andCompleted(bool) fields - Create a function called
removeTaskthat takes a slice ofTaskstructs and an index (int) as parameters - Inside the
removeTaskfunction, return a new slice with the task at the given index removed by usingappendto combine the elements before and after the target index - Parse the task data from the second input to create your slice of tasks:
- Split the input by commas to get individual task entries
- For each entry, split by colon to separate the name and status
- Convert the status string to a boolean (
"true"becomestrue,"false"becomesfalse)
- Convert the third input string to an integer to get the task index
- Store the name of the task to be removed before calling the
removeTaskfunction - Call your
removeTaskfunction with your slice and the index, storing the returned slice - After removing the task, display all remaining tasks using the same format as previous challenges:
- For completed tasks:
"[x] [task_name]" - For incomplete tasks:
"[ ] [task_name]"
- For completed tasks:
- Print a confirmation message:
"Task '[task_name]' removed successfully!" - Print the updated summary:
"Total: [total_count] tasks ([completed_count] completed, [incomplete_count] remaining)"
Use the strconv package to convert the index string to an integer. This challenge demonstrates how to use append to reconstruct slices by combining portions before and after a target element, effectively removing items from your collection while maintaining the order of remaining elements.
Try it yourself
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type Task struct {
Name string
Completed bool
}
func completeTask(tasks *[]Task, index int) {
(*tasks)[index].Completed = true
}
func main() {
// Read input using bufio.Scanner to handle spaces properly
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
_ = scanner.Text() // Read but don't use the number of tasks
scanner.Scan()
taskDataStr := scanner.Text()
scanner.Scan()
indexStr := scanner.Text()
// Parse task data
taskEntries := strings.Split(taskDataStr, ",")
tasks := make([]Task, len(taskEntries))
for i, entry := range taskEntries {
parts := strings.Split(entry, ":")
if len(parts) >= 2 {
name := parts[0]
status := parts[1] == "true"
tasks[i] = Task{Name: name, Completed: status}
}
}
// Convert index string to integer
index, _ := strconv.Atoi(indexStr)
// Complete the task
taskName := tasks[index].Name
completeTask(&tasks, index)
// Display all tasks
for _, task := range tasks {
if task.Completed {
fmt.Printf("[x] %s\n", task.Name)
} else {
fmt.Printf("[ ] %s\n", task.Name)
}
}
// Print confirmation message
fmt.Printf("Task '%s' marked as completed!\n", taskName)
// Count completed and incomplete tasks
completedCount := 0
for _, task := range tasks {
if task.Completed {
completedCount++
}
}
incompleteCount := len(tasks) - completedCount
// Print summary
fmt.Printf("Total: %d tasks (%d completed, %d remaining)\n", len(tasks), completedCount, incompleteCount)
}All lessons in Logic & Flow
1Advanced Control Flow
Switch with `fallthrough`Breaking from Nested LoopsContinuing a Specific LoopThe `goto` StatementRecap - Advanced Loop Control4Project: Simple Task List
Project SetupAdding a Task2Structs and Methods
Defining Methods on StructsValue ReceiversPointer ReceiversChoosing ReceiversMethods vs FunctionsRecap - Struct Behavior5Maps In-Depth
Maps of StructsPointers as Map ValuesTesting for Nil MapsComparing MapsRecap - Word Frequency Counter3Interfaces (The Basics)
What is an Interface?Defining an InterfaceImplementing an InterfaceUsing Interface TypesEmpty InterfaceType AssertionsType SwitchRecap - Shapes and Behaviors