github.com/clubpay/ronykit/kit@v0.14.4-0.20240515065620-d0dace45cbc7/utils/array.go (about) 1 package utils 2 3 // Filter returns a new slice containing only the elements in tt for which the match function returns true. 4 // 5 // type User struct { 6 // Name string 7 // Age int 8 // Active bool 9 // } 10 // 11 // var users = []User{ 12 // {"Tom", 20, true}, 13 // {"Jack", 22, false}, 14 // {"Mary", 18, true}, 15 // } 16 // 17 // var activeUsers = qkit.Filter(func(u User) bool { 18 // return u.Active 19 // }, users) 20 // 21 // fmt.Println(activeUsers) 22 // 23 // Playground: https://go.dev/play/p/70YOKRs79OF 24 func Filter[T any](match func(src T) bool, tt []T) []T { 25 ftt := make([]T, 0, len(tt)) 26 for _, t := range tt { 27 if match(t) { 28 ftt = append(ftt, t) 29 } 30 } 31 32 return ftt[:len(ftt):len(ftt)] 33 } 34 35 // Map applies the transformer function to each element of the slice ss. 36 // The result is a slice of the same length as ss, where the kth element is transformer(ss[k]). 37 // 38 // type User struct { 39 // Name string 40 // Age int 41 // } 42 // 43 // var users = []User{ 44 // {"Tom", 20}, 45 // {"Jack", 22}, 46 // {"Mary", 18}, 47 // } 48 // 49 // var names = qkit.Map(func(u User) string { 50 // return u.Name 51 // }, users) 52 // 53 // fmt.Println(names) 54 // 55 // Playground: https://go.dev/play/p/wKIa32-rMDn 56 func Map[S, D any](transformer func(src S) D, ss []S) []D { 57 dd := make([]D, len(ss)) 58 for k, src := range ss { 59 dd[k] = transformer(src) 60 } 61 62 return dd 63 } 64 65 // Reduce [T, R] reduces the slice tt to a single value r using the reducer 66 // function. The reducer function takes the current reduced value r and the 67 // current slice value t and returns a new reduced value. 68 // 69 // type User struct { 70 // Name string 71 // Age int 72 // } 73 // 74 // var users = []User{ 75 // {"Tom", 20}, 76 // {"Jack", 22}, 77 // {"Mary", 18}, 78 // } 79 // 80 // var totalAge = qkit.Reduce(func(r int, u User) int { 81 // return r + u.Age 82 // }, users) 83 // 84 // fmt.Println(totalAge) 85 // 86 // Playground: https://go.dev/play/p/gf9evzMIMIK 87 func Reduce[T, R any](reducer func(r R, t T) R, tt []T) R { 88 var r R 89 for _, t := range tt { 90 r = reducer(r, t) 91 } 92 93 return r 94 } 95 96 // Paginate will call the given function with start and end indexes 97 // for a slice of the given size. 98 // 99 // type User struct { 100 // Name string 101 // Age int 102 // } 103 // 104 // var users = []User{ 105 // {"Tom", 20}, 106 // {"Jack", 22}, 107 // {"Mary", 18}, 108 // {"Tommy", 20}, 109 // {"Lin", 22}, 110 // } 111 // 112 // qkit.Paginate(users, 2, func(start, end int) error { 113 // fmt.Println(users[start:end]) 114 // return nil 115 // }) 116 // 117 // Playground: https://go.dev/play/p/aDiVJEKjgwW 118 func Paginate[T any](arr []T, pageSize int, fn func(start, end int) error) error { 119 start := 0 120 for { 121 end := start + pageSize 122 if end > len(arr) { 123 end = len(arr) 124 } 125 err := fn(start, end) 126 if err != nil { 127 return err 128 } 129 start = end 130 if start >= len(arr) { 131 break 132 } 133 } 134 135 return nil 136 } 137 138 // MapToArray converts a map's values to a slice. 139 func MapToArray[K comparable, V any](s map[K]V) []V { 140 arr := make([]V, 0, len(s)) 141 for _, v := range s { 142 arr = append(arr, v) 143 } 144 145 return arr 146 } 147 148 // MapKeysToArray converts a map's keys to a slice. 149 func MapKeysToArray[K comparable, V any](s map[K]V) []K { 150 arr := make([]K, 0, len(s)) 151 for k := range s { 152 arr = append(arr, k) 153 } 154 155 return arr 156 } 157 158 // ArrayToMap converts a slice to a map with the index as the key. 159 func ArrayToMap[V any](s []V) map[int]V { 160 m := make(map[int]V, len(s)) 161 for idx, v := range s { 162 m[idx] = v 163 } 164 165 return m 166 } 167 168 func ArrayToSet[T comparable](s []T) map[T]struct{} { 169 m := make(map[T]struct{}, len(s)) 170 for _, v := range s { 171 m[v] = struct{}{} 172 } 173 174 return m 175 } 176 177 func Contains[T comparable](s []T, v T) bool { 178 for _, vv := range s { 179 if vv == v { 180 return true 181 } 182 } 183 184 return false 185 } 186 187 func ContainsAny[T comparable](s []T, v []T) bool { 188 for _, vv := range v { 189 if Contains(s, vv) { 190 return true 191 } 192 } 193 194 return false 195 } 196 197 func ContainsAll[T comparable](s []T, v []T) bool { 198 for _, vv := range v { 199 if !Contains(s, vv) { 200 return false 201 } 202 } 203 204 return true 205 } 206 207 // First returns the first value found in the map for the given keys. 208 func First[K, V comparable](in map[K]V, keys ...K) (V, bool) { 209 var zero V 210 for _, k := range keys { 211 if v, ok := in[k]; ok { 212 return v, true 213 } 214 } 215 216 return zero, false 217 } 218 219 func FirstOr[K, V comparable](def V, in map[K]V, keys ...K) V { 220 v, ok := First(in, keys...) 221 if ok { 222 return v 223 } 224 225 return def 226 } 227 228 func ForEach[V any](in []V, fn func(*V)) { 229 for idx := range in { 230 fn(&in[idx]) 231 } 232 } 233 234 func AddUnique[T comparable](s []T, v T) []T { 235 if Contains(s, v) { 236 return s 237 } 238 239 return append(s, v) 240 }