sort.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package service
  2. import (
  3. "go-common/library/log"
  4. "sort"
  5. )
  6. type roomInfo struct {
  7. roomId int64
  8. value int64
  9. }
  10. type attrSortStruct struct {
  11. roomIdInfos []roomInfo
  12. value int64
  13. }
  14. type RoomInfoSlice []roomInfo
  15. func (a RoomInfoSlice) Len() int {
  16. return len(a)
  17. }
  18. func (a RoomInfoSlice) Swap(i, j int) {
  19. a[i], a[j] = a[j], a[i]
  20. }
  21. func (a RoomInfoSlice) Less(i, j int) bool {
  22. return a[j].value < a[i].value
  23. }
  24. func (s *Service) sort(attrsFilter map[int64]map[int64]*attrFilter, filterRoomData []*filterItem, Cond string, recId int) (roomIds []int64) {
  25. roomIds = make([]int64, 0)
  26. noSort := make([]int64, 0)
  27. attrSort := make(map[int64]*attrSortStruct)
  28. attrTag := make([]int64, 0)
  29. if len(attrsFilter) <= 0 {
  30. for _, attrResp := range filterRoomData {
  31. if attrResp == nil {
  32. continue
  33. }
  34. noSort = append(noSort, attrResp.item.RoomId)
  35. }
  36. } else {
  37. //需要排序的
  38. for _, attrResp := range filterRoomData {
  39. if attrResp == nil {
  40. continue
  41. }
  42. for _, attr := range attrResp.item.AttrList {
  43. if _, ok := attrsFilter[attr.AttrId][attr.AttrSubId]; ok {
  44. if _, ok := attrSort[attr.AttrId]; !ok {
  45. attrSort[attr.AttrId] = &attrSortStruct{}
  46. }
  47. // 如果有top
  48. // 小时榜特殊处理
  49. if attr.AttrId == attrType[_hourRankType] {
  50. attr.AttrValue = 10 - attr.AttrValue
  51. }
  52. attrSort[attr.AttrId].value = attrsFilter[attr.AttrId][attr.AttrSubId].top
  53. attrSort[attr.AttrId].roomIdInfos = append(attrSort[attr.AttrId].roomIdInfos, roomInfo{
  54. roomId: attrResp.item.RoomId,
  55. value: attr.AttrValue,
  56. })
  57. }
  58. }
  59. //or 逻辑需要非attr类型合并
  60. if attrResp.isTagHit {
  61. attrTag = append(attrTag, attrResp.item.RoomId)
  62. }
  63. }
  64. }
  65. log.Info("[sort]recId:%d, attrSort:%+v, Cond:%s, attrsFilter:%+v, filterRoomData:%+v", recId, attrSort, Cond, attrsFilter, filterRoomData)
  66. log.Info("[sort]recId:%d, attrTag:%+v, Cond:%s, attrsFilter:%+v, filterRoomData:%+v", recId, attrTag, Cond, attrsFilter, filterRoomData)
  67. log.Info("[sort]recId:%d, noSort:%+v, Cond:%s, attrsFilter:%+v, filterRoomData:%+v", recId, noSort, Cond, attrsFilter, filterRoomData)
  68. sortedList := make([][]int64, 0)
  69. //有top 需要排序的
  70. for _, obj := range attrSort {
  71. sortedList = append(sortedList, s.sortRoomList(obj.roomIdInfos, obj.value))
  72. }
  73. if len(sortedList) <= 0 {
  74. sortedList = append(sortedList, noSort)
  75. }
  76. // and 求交集
  77. if Cond == _condAnd {
  78. // 如果不填top
  79. roomIds = s.sliceIntersect(sortedList)
  80. }
  81. if Cond == _condOr {
  82. // or 条件时有些roomData可能没有attr,需要合并没有attr的
  83. sortedList = append(sortedList, attrTag)
  84. roomIds = s.sliceMerge(sortedList)
  85. }
  86. log.Info("[sort]recId:%d, roomIds:%+v, Cond:%s, attrsFilter:%+v, filterRoomData:%+v", recId, roomIds, Cond, attrsFilter, filterRoomData)
  87. return
  88. }
  89. func (s *Service) sortRoomList(roomIdInfos []roomInfo, value int64) (roomList []int64) {
  90. //value <= 0 不排序,直接返回
  91. if value <= 0 {
  92. for _, info := range roomIdInfos {
  93. roomList = append(roomList, info.roomId)
  94. }
  95. return
  96. }
  97. sort.Sort(RoomInfoSlice(roomIdInfos))
  98. // top
  99. if len(roomIdInfos) >= int(value) {
  100. roomIdInfos = roomIdInfos[:value]
  101. }
  102. for _, info := range roomIdInfos {
  103. roomList = append(roomList, info.roomId)
  104. }
  105. return
  106. }
  107. // 带去重 slice合并
  108. func (s *Service) sliceMerge(roomList [][]int64) (mergedSlice []int64) {
  109. duplicateMap := make(map[int64]bool)
  110. mergedSlice = make([]int64, 0)
  111. for _, list := range roomList {
  112. for _, roomId := range list {
  113. if _, ok := duplicateMap[roomId]; !ok {
  114. mergedSlice = append(mergedSlice, roomId)
  115. duplicateMap[roomId] = true
  116. }
  117. }
  118. }
  119. return
  120. }
  121. func (s *Service) sliceIntersect(roomList [][]int64) (mergedSlice []int64) {
  122. mergedSlice = make([]int64, 0)
  123. if len(roomList) == 0 {
  124. return
  125. }
  126. if len(roomList) == 1 {
  127. mergedSlice = roomList[0]
  128. return
  129. }
  130. if len(roomList) >= 2 {
  131. i := 3
  132. mergedSlice = s.intersect(roomList[0], roomList[1])
  133. for {
  134. if len(roomList) < i {
  135. break
  136. }
  137. mergedSlice = s.intersect(mergedSlice, roomList[int64(i-1)])
  138. i++
  139. }
  140. }
  141. return
  142. }
  143. // 带去重 slice交集 slice已排序
  144. func (s *Service) intersect(nums1 []int64, nums2 []int64) (IntersectSlice []int64) {
  145. IntersectSlice = make([]int64, 0)
  146. x := 0
  147. y := 0
  148. for {
  149. if x < len(nums1) && y < len(nums2) {
  150. if nums1[x] == nums2[y] {
  151. IntersectSlice = append(IntersectSlice, nums1[x])
  152. x++
  153. y++
  154. } else if nums1[x] > nums2[y] {
  155. y++
  156. } else {
  157. x++
  158. }
  159. } else {
  160. break
  161. }
  162. }
  163. return
  164. }