slice_tree.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package utils
  2. import (
  3. "fmt"
  4. "github.com/gogf/gf/frame/g"
  5. "github.com/gogf/gf/util/gconv"
  6. "reflect"
  7. )
  8. //有层级关系的数组,父级-》子级 排序
  9. func ParentSonSort(list g.List, params ...interface{}) g.List {
  10. args := make([]interface{}, 8)
  11. for k, v := range params {
  12. if k == 8 {
  13. break
  14. }
  15. args[k] = v
  16. }
  17. var (
  18. pid int //父级id
  19. level int //层级数
  20. fieldName string //父级id键名
  21. id string //id键名
  22. levelName string //层级名称
  23. title string //标题名称
  24. breaks int //中断层级
  25. prefixStr string //字符串前缀
  26. )
  27. pid = gconv.Int(GetSliceByKey(args, 0, 0))
  28. level = gconv.Int(GetSliceByKey(args, 1, 0))
  29. fieldName = gconv.String(GetSliceByKey(args, 2, "pid"))
  30. id = gconv.String(GetSliceByKey(args, 3, "id"))
  31. levelName = gconv.String(GetSliceByKey(args, 4, "flg"))
  32. title = gconv.String(GetSliceByKey(args, 5, "title"))
  33. breaks = gconv.Int(GetSliceByKey(args, 6, -1))
  34. prefixStr = gconv.String(GetSliceByKey(args, 7, "─"))
  35. //定义一个新slice用于返回
  36. var returnSlice g.List
  37. for _, v := range list {
  38. if pid == gconv.Int(v[fieldName]) {
  39. v[levelName] = level
  40. levelClone := level
  41. titlePrefix := ""
  42. for {
  43. if levelClone < 0 {
  44. break
  45. }
  46. titlePrefix += prefixStr
  47. levelClone--
  48. }
  49. titlePrefix = "├" + titlePrefix
  50. if level == 0 {
  51. v["title_prefix"] = ""
  52. } else {
  53. v["title_prefix"] = titlePrefix
  54. }
  55. v["title_show"] = fmt.Sprintf("%s%s", v["title_prefix"], v[title])
  56. returnSlice = append(returnSlice, v)
  57. if breaks != -1 && breaks == level {
  58. continue
  59. }
  60. args[0] = v[id]
  61. args[1] = level + 1
  62. newSlice2 := ParentSonSort(list, args...)
  63. if len(newSlice2) > 0 {
  64. returnSlice = append(returnSlice, newSlice2...)
  65. }
  66. }
  67. }
  68. return returnSlice
  69. }
  70. //有层级关系的数组 ,将子级压入到父级(树形结构)
  71. func PushSonToParent(list g.List, params ...interface{}) g.List {
  72. args := make([]interface{}, 7)
  73. for k, v := range params {
  74. if k == 7 {
  75. break
  76. }
  77. args[k] = v
  78. }
  79. var (
  80. pid int //父级id
  81. fieldName string //父级id键名
  82. id string //id键名
  83. key string //子级数组键名
  84. filter string //过滤键名
  85. filterVal interface{} //过滤的值
  86. showNoChild bool //是否显示不存在的子级健
  87. )
  88. pid = gconv.Int(GetSliceByKey(args, 0, 0))
  89. fieldName = gconv.String(GetSliceByKey(args, 1, "pid"))
  90. id = gconv.String(GetSliceByKey(args, 2, "id"))
  91. key = gconv.String(GetSliceByKey(args, 3, "children"))
  92. filter = gconv.String(GetSliceByKey(args, 4, ""))
  93. filterVal = GetSliceByKey(args, 5, nil)
  94. showNoChild = gconv.Bool(GetSliceByKey(args, 6, true))
  95. var returnList g.List
  96. for _, v := range list {
  97. if gconv.Int(v[fieldName]) == pid {
  98. if filter != "" {
  99. if reflect.DeepEqual(v[filter], filterVal) {
  100. args[0] = v[id]
  101. child := PushSonToParent(list, args...)
  102. if child != nil || showNoChild {
  103. v[key] = child
  104. }
  105. returnList = append(returnList, v)
  106. }
  107. } else {
  108. args[0] = v[id]
  109. child := PushSonToParent(list, args...)
  110. if child != nil || showNoChild {
  111. v[key] = child
  112. }
  113. returnList = append(returnList, v)
  114. }
  115. }
  116. }
  117. return returnList
  118. }
  119. //获取切片里的值 若为nil 可设置默认值val
  120. func GetSliceByKey(args []interface{}, key int, val interface{}) interface{} {
  121. var value interface{}
  122. if args[key] != nil {
  123. value = args[key]
  124. } else {
  125. value = val
  126. }
  127. return value
  128. }
  129. //有层级关系的数组,通过父级id查找所有子级id数组
  130. func FindSonByParentId(list g.List, fid int, flg, flgV string) g.List {
  131. newList := make(g.List, 0, len(list))
  132. for _, v := range list {
  133. if gconv.Int(v[flg]) == fid {
  134. newList = append(newList, v)
  135. fList := FindSonByParentId(list, gconv.Int(v[flgV]), flg, flgV)
  136. newList = append(newList, fList...)
  137. }
  138. }
  139. return newList
  140. }
  141. //有层级关系的数组,通过子级fid查找所有父级数组
  142. func findParentBySonPid(list g.List, id int, params ...interface{}) g.List {
  143. args := make([]interface{}, 4)
  144. for k, v := range params {
  145. if k == 4 {
  146. break
  147. }
  148. args[k] = v
  149. }
  150. var (
  151. filter = gconv.String(GetSliceByKey(args, 0, "filter")) //过滤键名
  152. fPid = gconv.String(GetSliceByKey(args, 1, "pid")) //父级id字段键名
  153. filterValue = GetSliceByKey(args, 2, nil) //过滤键值
  154. fid = gconv.String(GetSliceByKey(args, 3, "id")) //id字段键名
  155. )
  156. rList := make(g.List, 0, len(list))
  157. for _, v := range list {
  158. if gconv.Int(v[fid]) == id {
  159. if fv, ok := v[filter]; ok {
  160. if reflect.DeepEqual(fv, filterValue) {
  161. rList = append(rList, v)
  162. }
  163. } else {
  164. rList = append(rList, v)
  165. }
  166. r := findParentBySonPid(list, gconv.Int(v[fPid]), filter, fPid, filterValue, fid)
  167. rList = append(rList, r...)
  168. }
  169. }
  170. return rList
  171. }