123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package main
- import (
- "fmt"
- "reflect"
- )
- // Person 结构体
- type Person struct {
- Name string
- Country string
- City string
- }
- // GroupByBuilder 用于构建多级分组
- type GroupByBuilder[T any] struct {
- data []T
- groups map[string]interface{}
- keyFuncs []func(T) (string, string)
- }
- // NewGroupByBuilder 创建一个新的 GroupByBuilder 实例
- func NewGroupByBuilder[T any](data []T) *GroupByBuilder[T] {
- return &GroupByBuilder[T]{
- data: data,
- }
- }
- // Group 添加一个分组键函数
- func (b *GroupByBuilder[T]) Group(fieldName string) *GroupByBuilder[T] {
- keyFunc := func(item T) (string, string) {
- v := reflect.ValueOf(item)
- f := v.FieldByName(fieldName)
- if !f.IsValid() {
- panic(fmt.Sprintf("Field %s does not exist in the provided type", fieldName))
- }
- return fieldName, f.String()
- }
- b.keyFuncs = append(b.keyFuncs, keyFunc)
- return b
- }
- // Build 构建分组
- func (b *GroupByBuilder[T]) Build() *GroupByResult[T] {
- if len(b.keyFuncs) == 0 {
- return &GroupByResult[T]{groups: map[string]interface{}{}}
- }
- groups := make(map[string]interface{})
- for _, item := range b.data {
- currentLevel := groups
- for _, keyFunc := range b.keyFuncs {
- _, fieldValue := keyFunc(item)
- if currentLevel[fieldValue] == nil {
- currentLevel[fieldValue] = make(map[string]interface{})
- }
- nextLevel, ok := currentLevel[fieldValue].(map[string]interface{})
- if !ok {
- panic(fmt.Sprintf("Expected map for key %s, got %T", fieldValue, currentLevel[fieldValue]))
- }
- currentLevel = nextLevel
- }
- // 最后一层添加数据
- if currentLevel["items"] == nil {
- currentLevel["items"] = make([]T, 0)
- }
- group, ok := currentLevel["items"].([]T)
- if !ok {
- panic(fmt.Sprintf("Expected slice for key items, got %T", currentLevel["items"]))
- }
- group = append(group, item)
- currentLevel["items"] = group
- }
- return &GroupByResult[T]{groups: groups}
- }
- // GroupByResult 存储分组结果
- type GroupByResult[T any] struct {
- groups map[string]interface{}
- }
- // GetAll 获取每个分组的所有元素
- func (r *GroupByResult[T]) GetAll() map[string]interface{} {
- return r.groups
- }
- // 示例数据
- var people = []Person{
- {Name: "Alice", Country: "USA", City: "New York"},
- {Name: "Bob", Country: "USA", City: "Los Angeles"},
- {Name: "Charlie", Country: "Canada", City: "Toronto"},
- {Name: "David", Country: "Canada", City: "Vancouver"},
- {Name: "Eve", Country: "USA", City: "New York"},
- {Name: "Frank", Country: "Canada", City: "Toronto"},
- }
- func main() {
- // 创建 GroupByBuilder 实例
- builder := NewGroupByBuilder(people)
- // 按 Country 和 City 分组
- grouped := builder.Group("Country").Build()
- // 打印每个分组的所有元素
- allElements := grouped.GetAll()
- fmt.Println("\nAll elements in each group:")
- printGroups(allElements, "")
- }
- // printGroups 递归打印分组
- func printGroups(groups map[string]interface{}, prefix string) {
- for k, v := range groups {
- switch v := v.(type) {
- case []Person:
- fmt.Printf("%s%s: ", prefix, k)
- for _, person := range v {
- fmt.Printf("%s, ", person.Name)
- }
- fmt.Println()
- case map[string]interface{}:
- newPrefix := prefix + k + " -> "
- printGroups(v, newPrefix)
- default:
- panic(fmt.Sprintf("Unexpected type: %T", v))
- }
- }
- }
|