从集合中移除元素
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 35 课,共 68 课。
有时你需要从集合中删除元素,Go 使用内置的 delete() 函数就能轻松完成。由于集合的底层实际上是映射,删除元素的方式与从映射中删除键完全相同。
要从集合中删除一个元素,请使用 delete() 函数,并传入集合和你想删除的元素:
delete(colors, "red")delete() 函数接受两个参数:映射(你的集合)和你想要删除的键。如果集合中存在该元素,它就会被删除。如果该元素不存在,函数不会执行任何操作,也不会引发错误。
这种行为非常适合集合,因为你通常希望确保某个元素不存在,无论它最初是否存在。此操作快速而高效,同时保留了 Go 底层映射实现带来的性能优势。
挑战
简单使用 Go 集合惯用写法构建一个图书馆图书管理系统,从不同类别的图书集合中移除图书。本挑战将演示如何使用 delete() 函数从集合中移除元素,同时跟踪移除过程。
你会收到两个输入:
- 一个字符串,其中包含以逗号分隔的小说类图书(例如,
"1984,Dune,Foundation,Neuromancer,Brave New World") - 一个字符串,其中包含以逗号分隔的待移除图书(例如,
"Dune,Harry Potter,Foundation,Twilight,1984")
你的任务是:
- 使用 Go 惯用写法
map[string]struct{}创建一个集合,用于存储小说类图书 - 按逗号拆分第一个输入字符串,获取每本图书的标题
- 使用空结构体字面量
{}作为值,将每本图书添加到集合中 - 按逗号拆分第二个输入字符串,获取待移除图书的列表
- 对于每本待移除的图书,使用逗号 ok 惯用写法检查它是否存在于集合中
- 显示每本正在处理的图书的移除过程:
- 如果图书存在于集合中:
"Removing: [book_title]" - 如果图书不存在于集合中:
"Not found: [book_title]"
- 如果图书存在于集合中:
- 使用
delete()函数移除集合中存在的图书 - 处理完所有移除请求后,显示摘要:
"Initial collection size: [initial_count]""Removal requests: [requests_count]""Books successfully removed: [removed_count]""Books not found: [not_found_count]""Final collection size: [final_count]"
- 最后,列出集合中所有剩余的图书:
- 标题:
"Remaining books in fiction collection:" - 每本图书单独占一行:
"- [book_title]" - 如果没有剩余图书:
"- Collection is empty"
- 标题:
使用 strings 包按逗号拆分输入字符串。本挑战将演示 delete() 函数如何安全地从 Go 集合中移除元素。即使尝试移除不存在的元素,也不会引发错误,因此它非常适合用于清理操作。
亲手试试
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strings"
)
func main() {
// 用 Scanner 读取输入,以支持包含空格的书名
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
fictionBooks := scanner.Text()
scanner.Scan()
booksToRemove := scanner.Text()
// 解析输入字符串
fictionList := strings.Split(fictionBooks, ",")
removeList := strings.Split(booksToRemove, ",")
// TODO: 在下方编写代码
// 1. 使用 map[string]struct{} 创建集合,存储小说书籍
// 2. 将 fictionList 中的每本书添加到集合中
// 3. 逐一处理 removeList 中的书,检查它是否存在
// 4. 显示移除过程,并使用 delete() 函数
// 5. 显示汇总统计信息
// 6. 列出集合中剩余的书
// 记得对剩余的书排序,确保输出顺序一致
_ = sort.Strings // 使用 sort 后删除这一行
_ = fmt.Println // 使用 fmt 后删除这一行
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Go 在线编译器