结构体映射
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 26 课,共 68 课。
将结构体作为值存储后,映射会变得非常强大。这种模式可以让你使用有意义的键来组织复杂的结构化数据,方便查找和获取。
将结构体用作映射的值时,你实际上是在创建一个集合,其中每个键都指向一条完整的数据记录。下面介绍如何声明并初始化这样的映射:
type Student struct {
ID int
Grade string
}
students := map[string]Student{
"Alice": {ID: 101, Grade: "A"},
"Bob": {ID: 102, Grade: "B"},
}你可以像执行其他映射操作一样,通过映射访问和处理结构体数据。要获取学生的信息,只需使用学生姓名作为键:
alice := students["Alice"]
fmt.Println(alice.ID) // 输出:101
fmt.Println(alice.Grade) // 输出:A这种模式在 Go 应用中非常常见,适合存储相关数据的集合,例如用户资料、产品目录或配置设置,这些场景既需要结构化数据,也需要基于键快速访问。
挑战
简单使用以结构体为值的映射,创建一个学生成绩管理系统。本挑战将展示如何使用有意义的键来组织复杂的学生数据,以便高效查找和检索。
你会收到两个输入:
- 一个表示学生人数的字符串(例如
"4") - 一个包含学生数据的字符串,格式为:
"name1:id1:grade1,name2:id2:grade2,name3:id3:grade3"(例如"Alice:101:A,Bob:102:B,Charlie:103:C,Diana:104:A")
你的任务是:
- 定义一个
Student结构体,包含以下字段:ID(int):学生的 ID 号Grade(string):学生的字母成绩
- 创建一个映射,其中键是学生姓名(字符串),值是
Student结构体 - 解析第二个输入中的学生数据:
- 按逗号拆分输入,获取每个学生的条目
- 对每个条目按冒号拆分,以分离姓名、ID 和成绩
- 将 ID 字符串转换为整数
- 创建一个
Student结构体,并以姓名为键将其添加到映射中
- 按姓名的字母顺序显示所有学生,格式为:
"[name]: ID [id], Grade [grade]" - 计算并显示成绩统计信息:
- 统计每个成绩(A、B、C、D、F)对应的学生人数
- 按照以下格式显示出现过的每个成绩对应的人数:
"Grade [grade]: [count] students" - 按字母顺序显示成绩(A、B、C、D、F)
- 找出并显示 ID 最高的学生,格式为:
"Highest ID: [name] ([id])" - 显示学生总人数:
"Total students: [count]"
使用 strconv 包将 ID 字符串转换为整数,并使用 sort 包按字母顺序排列学生姓名。本挑战将展示如何使用以结构体为值的映射,通过有意义的标识符高效组织和访问复杂的数据集合。
亲手试试
package main
import (
"fmt"
)
func main() {
// 读取输入
var numStudentsStr string
var studentData string
fmt.Scanln(&numStudentsStr)
fmt.Scanln(&studentData)
// TODO: 在这里定义 Student 结构体
// TODO: 创建一个 map 来存储学生(以姓名为键,以 Student 结构体为值)
// TODO: 解析学生数据并填充 map
// TODO: 按姓名的字母顺序显示所有学生
// TODO: 计算并显示成绩统计信息
// TODO: 找出并显示 ID 最大的学生
// TODO: 显示学生总数
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Go 在线编译器