sliceTest.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. // Person 结构体
  7. type Person struct {
  8. Name string
  9. Country string
  10. City string
  11. }
  12. // GroupByBuilder 用于构建多级分组
  13. type GroupByBuilder[T any] struct {
  14. data []T
  15. groups map[string]interface{}
  16. keyFuncs []func(T) (string, string)
  17. }
  18. // NewGroupByBuilder 创建一个新的 GroupByBuilder 实例
  19. func NewGroupByBuilder[T any](data []T) *GroupByBuilder[T] {
  20. return &GroupByBuilder[T]{
  21. data: data,
  22. }
  23. }
  24. // Group 添加一个分组键函数
  25. func (b *GroupByBuilder[T]) Group(fieldName string) *GroupByBuilder[T] {
  26. keyFunc := func(item T) (string, string) {
  27. v := reflect.ValueOf(item)
  28. f := v.FieldByName(fieldName)
  29. if !f.IsValid() {
  30. panic(fmt.Sprintf("Field %s does not exist in the provided type", fieldName))
  31. }
  32. return fieldName, f.String()
  33. }
  34. b.keyFuncs = append(b.keyFuncs, keyFunc)
  35. return b
  36. }
  37. // Build 构建分组
  38. func (b *GroupByBuilder[T]) Build() *GroupByResult[T] {
  39. if len(b.keyFuncs) == 0 {
  40. return &GroupByResult[T]{groups: map[string]interface{}{}}
  41. }
  42. groups := make(map[string]interface{})
  43. for _, item := range b.data {
  44. currentLevel := groups
  45. for _, keyFunc := range b.keyFuncs {
  46. _, fieldValue := keyFunc(item)
  47. if currentLevel[fieldValue] == nil {
  48. currentLevel[fieldValue] = make(map[string]interface{})
  49. }
  50. nextLevel, ok := currentLevel[fieldValue].(map[string]interface{})
  51. if !ok {
  52. panic(fmt.Sprintf("Expected map for key %s, got %T", fieldValue, currentLevel[fieldValue]))
  53. }
  54. currentLevel = nextLevel
  55. }
  56. // 最后一层添加数据
  57. if currentLevel["items"] == nil {
  58. currentLevel["items"] = make([]T, 0)
  59. }
  60. group, ok := currentLevel["items"].([]T)
  61. if !ok {
  62. panic(fmt.Sprintf("Expected slice for key items, got %T", currentLevel["items"]))
  63. }
  64. group = append(group, item)
  65. currentLevel["items"] = group
  66. }
  67. return &GroupByResult[T]{groups: groups}
  68. }
  69. // GroupByResult 存储分组结果
  70. type GroupByResult[T any] struct {
  71. groups map[string]interface{}
  72. }
  73. // GetAll 获取每个分组的所有元素
  74. func (r *GroupByResult[T]) GetAll() map[string]interface{} {
  75. return r.groups
  76. }
  77. // 示例数据
  78. var people = []Person{
  79. {Name: "Alice", Country: "USA", City: "New York"},
  80. {Name: "Bob", Country: "USA", City: "Los Angeles"},
  81. {Name: "Charlie", Country: "Canada", City: "Toronto"},
  82. {Name: "David", Country: "Canada", City: "Vancouver"},
  83. {Name: "Eve", Country: "USA", City: "New York"},
  84. {Name: "Frank", Country: "Canada", City: "Toronto"},
  85. }
  86. func main() {
  87. // 创建 GroupByBuilder 实例
  88. builder := NewGroupByBuilder(people)
  89. // 按 Country 和 City 分组
  90. grouped := builder.Group("Country").Build()
  91. // 打印每个分组的所有元素
  92. allElements := grouped.GetAll()
  93. fmt.Println("\nAll elements in each group:")
  94. printGroups(allElements, "")
  95. }
  96. // printGroups 递归打印分组
  97. func printGroups(groups map[string]interface{}, prefix string) {
  98. for k, v := range groups {
  99. switch v := v.(type) {
  100. case []Person:
  101. fmt.Printf("%s%s: ", prefix, k)
  102. for _, person := range v {
  103. fmt.Printf("%s, ", person.Name)
  104. }
  105. fmt.Println()
  106. case map[string]interface{}:
  107. newPrefix := prefix + k + " -> "
  108. printGroups(v, newPrefix)
  109. default:
  110. panic(fmt.Sprintf("Unexpected type: %T", v))
  111. }
  112. }
  113. }