slice.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // Package mhayaSlice code from: https://github.com/beego/beego/blob/develop/core/utils/slice.go
  2. package mhayaSlice
  3. import (
  4. "math/rand"
  5. "reflect"
  6. "strings"
  7. "time"
  8. cstring "github.com/mhaya/extend/string"
  9. cutils "github.com/mhaya/extend/utils"
  10. )
  11. func Int32In(v int32, sl []int32) (int, bool) {
  12. for i, vv := range sl {
  13. if vv == v {
  14. return i, true
  15. }
  16. }
  17. return 0, false
  18. }
  19. func Int64In(v int64, sl []int64) (int, bool) {
  20. for i, vv := range sl {
  21. if vv == v {
  22. return i, true
  23. }
  24. }
  25. return 0, false
  26. }
  27. // StringIn checks given string in string slice or not.
  28. func StringIn(v string, sl []string) (int, bool) {
  29. for i, vv := range sl {
  30. if vv == v {
  31. return i, true
  32. }
  33. }
  34. return 0, false
  35. }
  36. func StringInSlice(v string, sl []string) bool {
  37. _, ok := StringIn(v, sl)
  38. return ok
  39. }
  40. // InInterface checks given interface in interface slice.
  41. func InInterface(v interface{}, sl []interface{}) bool {
  42. for _, vv := range sl {
  43. if vv == v {
  44. return true
  45. }
  46. }
  47. return false
  48. }
  49. // RandList generate an int slice from min to max.
  50. func RandList(minValue, maxValue int) []int {
  51. if maxValue < minValue {
  52. minValue, maxValue = maxValue, minValue
  53. }
  54. length := maxValue - minValue + 1
  55. t0 := time.Now()
  56. rand.Seed(int64(t0.Nanosecond()))
  57. list := rand.Perm(length)
  58. for index := range list {
  59. list[index] += minValue
  60. }
  61. return list
  62. }
  63. // Merge merges interface slices to one slice.
  64. func Merge(slice1, slice2 []interface{}) (c []interface{}) {
  65. c = append(slice1, slice2...)
  66. return
  67. }
  68. // Reduce generates a new slice after parsing every value by reduce function
  69. func Reduce(slice []interface{}, a func(interface{}) interface{}) (destSlice []interface{}) {
  70. for _, v := range slice {
  71. destSlice = append(destSlice, a(v))
  72. }
  73. return
  74. }
  75. // Rand returns random one from slice.
  76. func Rand(a []interface{}) (b interface{}) {
  77. randNum := rand.Intn(len(a))
  78. b = a[randNum]
  79. return
  80. }
  81. // Sum sums all values in int64 slice.
  82. func Sum(intslice []int64) (sum int64) {
  83. for _, v := range intslice {
  84. sum += v
  85. }
  86. return
  87. }
  88. // Filter generates a new slice after filter function.
  89. func Filter(slice []interface{}, a func(interface{}) bool) (filterSlice []interface{}) {
  90. for _, v := range slice {
  91. if a(v) {
  92. filterSlice = append(filterSlice, v)
  93. }
  94. }
  95. return
  96. }
  97. // Diff returns diff slice of slice1 - slice2.
  98. func Diff(slice1, slice2 []interface{}) (diffSlice []interface{}) {
  99. for _, v := range slice1 {
  100. if !InInterface(v, slice2) {
  101. diffSlice = append(diffSlice, v)
  102. }
  103. }
  104. return
  105. }
  106. // Intersect returns slice that are present in all the slice1 and slice2.
  107. func Intersect(slice1, slice2 []interface{}) (diffSlice []interface{}) {
  108. for _, v := range slice1 {
  109. if InInterface(v, slice2) {
  110. diffSlice = append(diffSlice, v)
  111. }
  112. }
  113. return
  114. }
  115. // Chunk separates one slice to some sized slice.
  116. func Chunk(slice []interface{}, size int) (chunkSlice [][]interface{}) {
  117. if size >= len(slice) {
  118. chunkSlice = append(chunkSlice, slice)
  119. return
  120. }
  121. end := size
  122. for i := 0; i <= (len(slice) - size); i += size {
  123. chunkSlice = append(chunkSlice, slice[i:end])
  124. end += size
  125. }
  126. return
  127. }
  128. // Range generates a new slice from begin to end with step duration of int64 number.
  129. func Range(start, end, step int64) (intSlice []int64) {
  130. for i := start; i <= end; i += step {
  131. intSlice = append(intSlice, i)
  132. }
  133. return
  134. }
  135. // Pad prepends size number of val into slice.
  136. func Pad(slice []interface{}, size int, val interface{}) []interface{} {
  137. if size <= len(slice) {
  138. return slice
  139. }
  140. for i := 0; i < (size - len(slice)); i++ {
  141. slice = append(slice, val)
  142. }
  143. return slice
  144. }
  145. func Uniques[T comparable](slices ...[]T) []T {
  146. keys := map[T]struct{}{}
  147. for _, slice := range slices {
  148. for _, s := range slice {
  149. keys[s] = struct{}{}
  150. }
  151. }
  152. var uniqueSlice []T
  153. for t := range keys {
  154. uniqueSlice = append(uniqueSlice, t)
  155. }
  156. return uniqueSlice
  157. }
  158. // Unique cleans repeated values in slice.
  159. func Unique[T comparable](slice ...T) []T {
  160. return Uniques[T](slice)
  161. }
  162. // Shuffle shuffles a slice.
  163. func Shuffle(slice []interface{}) []interface{} {
  164. for i := 0; i < len(slice); i++ {
  165. a := rand.Intn(len(slice))
  166. b := rand.Intn(len(slice))
  167. slice[a], slice[b] = slice[b], slice[a]
  168. }
  169. return slice
  170. }
  171. func StringToInt(strSlice []string) []int {
  172. var intSlice []int
  173. for _, s := range strSlice {
  174. if cutils.IsNumeric(s) {
  175. val, ok := cstring.ToInt(s)
  176. if ok {
  177. intSlice = append(intSlice, val)
  178. }
  179. }
  180. }
  181. return intSlice
  182. }
  183. func StringToInt32(strSlice []string) []int32 {
  184. var intSlice []int32
  185. for _, s := range strSlice {
  186. if cutils.IsNumeric(s) {
  187. val, ok := cstring.ToInt32(s)
  188. if ok {
  189. intSlice = append(intSlice, val)
  190. }
  191. }
  192. }
  193. return intSlice
  194. }
  195. func StringToInt64(strSlice []string) []int64 {
  196. var intSlice []int64
  197. for _, s := range strSlice {
  198. if cutils.IsNumeric(s) {
  199. val, ok := cstring.ToInt64(s)
  200. if ok {
  201. intSlice = append(intSlice, val)
  202. }
  203. }
  204. }
  205. return intSlice
  206. }
  207. // IsSlice checks whether given value is array/slice.
  208. // Note that it uses reflect internally implementing this feature.
  209. func IsSlice(value interface{}) bool {
  210. rv := reflect.ValueOf(value)
  211. kind := rv.Kind()
  212. if kind == reflect.Ptr {
  213. rv = rv.Elem()
  214. kind = rv.Kind()
  215. }
  216. switch kind {
  217. case reflect.Array, reflect.Slice:
  218. return true
  219. default:
  220. return false
  221. }
  222. }
  223. func IsEmptyWithString(p []string) bool {
  224. for _, s := range p {
  225. if strings.TrimSpace(s) == "" {
  226. return true
  227. }
  228. }
  229. return false
  230. }