slice.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package otherutils
  2. import "fmt"
  3. // CompareResult represents the result of slice comparison
  4. type CompareResult int
  5. const (
  6. Different CompareResult = -1 // Elements are different
  7. SameUnordered CompareResult = 0 // Same elements but different order
  8. SameOrdered CompareResult = 1 // Same elements in same order
  9. )
  10. // RemoveFirst removes the first element that matches the predicate.
  11. // Note: This function modifies the original slice and does not preserve order
  12. // as it moves the last element to the removed position.
  13. func RemoveFirst[K any](sl []K, f func(v1 K) bool) []K {
  14. for k, v := range sl {
  15. if f(v) {
  16. sl[k] = sl[len(sl)-1]
  17. return sl[:len(sl)-1]
  18. }
  19. }
  20. return sl
  21. }
  22. // InSlice checks if a slice contains a specific element.
  23. func InSlice[K comparable](src []K, sub K) bool {
  24. for _, v := range src {
  25. if v == sub {
  26. return true
  27. }
  28. }
  29. return false
  30. }
  31. // RemoveSliceOrdered removes the first occurrence of sub from src while preserving order.
  32. // Returns the modified slice.
  33. func RemoveSliceOrdered[K comparable](src []K, sub K) []K {
  34. for k, v := range src {
  35. if v == sub {
  36. copy(src[k:], src[k+1:])
  37. return src[:len(src)-1]
  38. }
  39. }
  40. return src
  41. }
  42. // RemoveSliceUnordered removes the first occurrence of sub from src.
  43. // Note: This function does not preserve the original order as it moves
  44. // the last element to the removed position for better performance.
  45. func RemoveSliceUnordered[K comparable](src []K, sub K) []K {
  46. for k, v := range src {
  47. if v == sub {
  48. src[k] = src[len(src)-1]
  49. return src[:len(src)-1]
  50. }
  51. }
  52. return src
  53. }
  54. // RemoveOneFromSlice removes the first occurrence of an element that matches the predicate.
  55. func RemoveOneFromSlice[K any](src []K, cmp func(K) bool) []K {
  56. for k, v := range src {
  57. if cmp(v) {
  58. copy(src[k:], src[k+1:])
  59. return src[:len(src)-1]
  60. }
  61. }
  62. return src
  63. }
  64. // SubSlice returns a new slice containing elements from src that are not in sub.
  65. // Note: This function modifies the original slice to avoid memory allocation.
  66. // Example: [1,1,2,3] - [1,1,2,4] = [3]
  67. func SubSlice[K comparable](src []K, sub []K) []K {
  68. // 组织MAP表
  69. subMap := make(map[K]int, len(sub))
  70. for _, v := range sub {
  71. subMap[v] += 1
  72. }
  73. remove := func(val K) bool {
  74. v, ok := subMap[val]
  75. if !ok {
  76. return false
  77. }
  78. if v > 1 {
  79. subMap[val] -= 1
  80. } else {
  81. delete(subMap, val)
  82. }
  83. return true
  84. }
  85. index := 0
  86. for _, v := range src {
  87. if remove(v) {
  88. continue
  89. }
  90. src[index] = v
  91. index += 1
  92. }
  93. src = src[:index]
  94. return src
  95. }
  96. // CompareSlice compares two slices and returns the result.
  97. func CompareSlice[K comparable](p1 []K, p2 []K) CompareResult {
  98. // 长度不等直接-1
  99. if len(p1) != len(p2) {
  100. return Different
  101. }
  102. // 逐个比较每个相等则为1
  103. allEq := true
  104. for k, v := range p1 {
  105. if v != p2[k] {
  106. allEq = false
  107. break
  108. }
  109. }
  110. if allEq {
  111. return SameOrdered
  112. }
  113. // 个数统计,每个相等则为0
  114. p1Nums := make(map[K]int)
  115. for _, v := range p1 {
  116. p1Nums[v] += 1
  117. }
  118. p2Nums := make(map[K]int)
  119. for _, v := range p2 {
  120. p2Nums[v] += 1
  121. }
  122. if len(p1Nums) != len(p2Nums) {
  123. return Different
  124. }
  125. for k, v := range p1Nums {
  126. n := p2Nums[k]
  127. if n != v {
  128. return Different
  129. }
  130. }
  131. return SameUnordered
  132. }
  133. // CompareMap compares two maps and returns true if they are equal, false otherwise.
  134. func CompareMap[K comparable, V comparable](p1 map[K]V, p2 map[K]V) bool {
  135. //长度不等则为-1
  136. if len(p1) != len(p2) {
  137. return false
  138. }
  139. for k, v := range p1 {
  140. n, ok := p2[k]
  141. if !ok {
  142. return false
  143. }
  144. if n != v {
  145. return false
  146. }
  147. }
  148. return true
  149. }
  150. func CloneSlice[T any](slice []T) []T {
  151. newSlice := make([]T, len(slice))
  152. copy(newSlice, slice)
  153. return newSlice
  154. }
  155. func TestSlice() {
  156. //[1,1,2,3] - [1,1,2,4] = [3]
  157. fmt.Println(SubSlice([]int{1, 1, 2, 3}, []int{1, 1, 2, 4}))
  158. fmt.Println(SubSlice([]int{1, 1, 2, 3}, []int{}))
  159. fmt.Println(SubSlice([]int{}, []int{1, 1, 2, 4}))
  160. }