如何用Go语言从结构体切片中找出最频繁年龄并输出对应姓名
声明:我并非专业开发者,接触Go语言约8个月(通过Udemy和YouTube学习),仍不知如何解决如下简单问题。
问题概述
- 从解码JSON文件得到的结构体切片中找出出现最频繁的
age字段(JSON包含字符串name和整数age)。 - 根据年龄的最高出现频率输出对应的
name。 - 输出的姓名需按字母顺序排序。
输入(JSON)
[ {"name": "John","age": 15}, {"name": "Peter","age": 12}, {"name": "Roger","age": 12}, {"name": "Anne","age": 44}, {"name": "Marry","age": 15}, {"name": "Nancy","age": 15} ]
输出
['John', 'Mary', 'Nancy']
说明
数据中出现最频繁的年龄是15(出现3次),因此输出应为这三人的姓名数组,即['John', 'Mary', 'Nancy']。
例外情况
- 若有多个年龄的最高出现次数相同,需将数据拆分并输出为不同数组(例如当Anne的年龄为12时,结果为:
['John', 'Mary', 'Nancy'],['Anne','Peter','Roger'])
尝试的Go代码
package main import ( "encoding/json" "fmt" "os" "sort" ) // 定义对应JSON的结构体 type Passanger struct { Name string `json:"name"` Age int `json:"age"` } func main() { // 读取JSON文件 content, err := os.ReadFile("passanger.json") if err != nil { fmt.Println(err.Error()) } // 将JSON解析为结构体切片 var passangers []Passanger err2 := json.Unmarshal(content, &passangers) if err2 != nil { fmt.Println("Error JSON Unmarshalling") fmt.Println(err2.Error()) } // 遍历打印年龄(仅测试用) for _, v := range passangers { fmt.Println(v.Age) } // TODO: 找出出现频率最高的年龄,对应姓名排序输出 }
参考过的代码片段
我尝试过参考一些编程题解,但不知道如何适配到当前场景:
- 求多数元素的函数,但不知道如何把Passanger切片中的
age提取出来传入:
func majorityElement(arr int) int { sort.Ints(arr) return arr[len(arr)/2] }
- 用map统计整数频率的示例,但不知道如何同时处理
age和name字段:
func main(){ arr := []int{90, 70, 30, 30, 10, 80, 40, 50, 40, 30} freq := make(map[int]int) for _ , num := range arr { freq[num] = freq[num]+1 } fmt.Println("Frequency of the Array is : ", freq) }
解决方案
我们可以分三步完成需求:统计年龄频率、分组姓名、找出最高频率的分组并排序。
完整代码如下:
package main import ( "encoding/json" "fmt" "os" "sort" ) type Passanger struct { Name string `json:"name"` Age int `json:"age"` } func main() { // 读取并解析JSON文件 content, err := os.ReadFile("passanger.json") if err != nil { fmt.Printf("读取文件失败: %v\n", err) return } var passangers []Passanger err = json.Unmarshal(content, &passangers) if err != nil { fmt.Printf("解析JSON失败: %v\n", err) return } // 1. 统计每个年龄的出现次数,同时按年龄分组存储姓名 ageFreq := make(map[int]int) // key:年龄,value:出现次数 ageToNames := make(map[int][]string) // key:年龄,value:对应姓名列表 for _, p := range passangers { ageFreq[p.Age]++ ageToNames[p.Age] = append(ageToNames[p.Age], p.Name) } // 2. 找出最高出现频率 maxFreq := 0 for _, freq := range ageFreq { if freq > maxFreq { maxFreq = freq } } // 3. 收集所有频率等于maxFreq的年龄对应的姓名列表,并排序 var result [][]string for age, names := range ageToNames { if ageFreq[age] == maxFreq { // 对姓名按字母顺序排序 sort.Strings(names) result = append(result, names) } } // 输出结果 fmt.Println(result) }
代码解释
- 统计与分组:用两个map分别记录每个年龄的出现次数,以及每个年龄对应的所有姓名。遍历结构体切片时,同时更新这两个map。
- 找最高频率:遍历
ageFreq找到最大的出现次数maxFreq。 - 生成结果:筛选出所有频率等于
maxFreq的年龄组,对每组姓名排序后加入结果切片,最后输出。
内容的提问来源于stack exchange,提问作者ariejanuar
相关产品推荐
相关产品推荐

