github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zarray/array.go (about) 1 // Package zarray provides array operations 2 package zarray 3 4 import ( 5 "errors" 6 "fmt" 7 "math/rand" 8 ) 9 10 // Array insert, delete, random access according to the subscript operation, the data is interface type 11 type Array struct { 12 data []interface{} 13 size int 14 } 15 16 // ErrIllegalIndex illegal index 17 var ErrIllegalIndex = errors.New("illegal index") 18 19 // New array initialization memory 20 func NewArray(capacity ...int) (array *Array) { 21 c := 5 22 if len(capacity) >= 1 && capacity[0] != 0 { 23 c = capacity[0] 24 } 25 26 return &Array{ 27 data: make([]interface{}, c), 28 size: 0, 29 } 30 } 31 32 // Deprecated: please use NewArray 33 func New(capacity ...int) (array *Array) { 34 return NewArray(capacity...) 35 } 36 37 // Copy an array 38 func CopyArray(arr interface{}) (array *Array, err error) { 39 data, ok := arr.([]interface{}) 40 if ok { 41 l := len(data) 42 array = NewArray(l) 43 for i := 0; i < l; i++ { 44 array.Push(data[i]) 45 } 46 } else { 47 err = errors.New("type of error") 48 } 49 return 50 } 51 52 // Deprecated: please use CopyArray 53 func Copy(arr interface{}) (array *Array, err error) { 54 return CopyArray(arr) 55 } 56 57 // determine whether the index is out of bounds 58 func (arr *Array) checkIndex(index int) (bool, int) { 59 size := arr.size 60 if index < 0 || index >= size { 61 return true, size 62 } 63 64 return false, size 65 } 66 67 // array expansion 68 func (arr *Array) resize(capacity int) { 69 newArray := make([]interface{}, capacity) 70 for i := 0; i < arr.size; i++ { 71 newArray[i] = arr.data[i] 72 } 73 arr.data = newArray 74 } 75 76 // CapLength get array capacity 77 func (arr *Array) CapLength() int { 78 return cap(arr.data) 79 } 80 81 // Length get array length 82 func (arr *Array) Length() int { 83 return arr.size 84 } 85 86 // IsEmpty determine whether the array is empty 87 func (arr *Array) IsEmpty() bool { 88 return arr.size == 0 89 } 90 91 // Unshift insert element into array header 92 func (arr *Array) Unshift(value interface{}) error { 93 return arr.Add(0, value) 94 } 95 96 // Push insert element to end of array 97 func (arr *Array) Push(values ...interface{}) { 98 for i := 0; i < len(values); i++ { 99 _ = arr.Add(arr.size, values[i]) 100 } 101 } 102 103 // Add in the index position insert the element 104 func (arr *Array) Add(index int, value interface{}) (err error) { 105 if index < 0 || index > arr.size { 106 err = errors.New("sdd failed. Require index >= 0 and index <= size") 107 return 108 } 109 110 // If the current number of elements is equal to the arr capacity, 111 // the arr will be expanded to twice the original size 112 capLen := arr.CapLength() 113 if arr.size == capLen { 114 arr.resize(capLen * 2) 115 } 116 117 for i := arr.size - 1; i >= index; i-- { 118 arr.data[i+1] = arr.data[i] 119 } 120 121 arr.data[index] = value 122 arr.size++ 123 return 124 } 125 126 // Map ForEcho traversing generates a new array 127 func (arr *Array) Map(fn func(int, interface{}) interface{}) *Array { 128 values, _ := Copy(arr.data) 129 for i := 0; i < values.Length(); i++ { 130 value, _ := values.Get(i) 131 _ = values.Set(i, fn(i, value)) 132 } 133 return values 134 } 135 136 // Get the element corresponding to the index position 137 func (arr *Array) Get(index int, def ...interface{}) (value interface{}, err error) { 138 if r, _ := arr.checkIndex(index); r { 139 err = ErrIllegalIndex 140 if dValue, dErr := GetInf(def, 0, nil); dErr == nil { 141 value = dValue 142 } 143 return 144 } 145 146 value = arr.data[index] 147 return 148 } 149 150 // Set modify the element at the index position 151 func (arr *Array) Set(index int, value interface{}) (err error) { 152 if r, _ := arr.checkIndex(index); r { 153 return ErrIllegalIndex 154 } 155 156 arr.data[index] = value 157 return 158 } 159 160 // Contains find if there are elements in the array 161 func (arr *Array) Contains(value interface{}) bool { 162 for i := 0; i < arr.size; i++ { 163 if arr.data[i] == value { 164 return true 165 } 166 } 167 168 return false 169 } 170 171 // Index find array by index, index range [0, n-1] (not found, return - 1) 172 func (arr *Array) Index(value interface{}) int { 173 for i := 0; i < arr.size; i++ { 174 if arr.data[i] == value { 175 return i 176 } 177 } 178 179 return -1 180 } 181 182 // Remove delete the element at index position and return 183 func (arr *Array) Remove(index int, l ...int) (value []interface{}, err error) { 184 r, size := arr.checkIndex(index) 185 186 if r { 187 err = ErrIllegalIndex 188 return 189 } 190 removeL := 1 191 if len(l) > 0 && l[0] > 1 { 192 removeL = l[0] 193 } 194 195 value = make([]interface{}, removeL) 196 copy(value, arr.data[index:index+removeL]) 197 for i := index + removeL; i < arr.size; i++ { 198 arr.data[i-removeL] = arr.data[i] 199 arr.data[i] = nil 200 } 201 202 arr.size = size - removeL 203 capLen := arr.CapLength() 204 if arr.size == capLen/4 && capLen/2 != 0 { 205 arr.resize(capLen / 2) 206 } 207 return 208 } 209 210 // Shift delete the first element of the array 211 func (arr *Array) Shift() (interface{}, error) { 212 return arr.Remove(0) 213 } 214 215 // Pop delete end element 216 func (arr *Array) Pop() (interface{}, error) { 217 return arr.Remove(arr.size - 1) 218 } 219 220 // RemoveValue removes the specified element from the array 221 func (arr *Array) RemoveValue(value interface{}) (e interface{}, err error) { 222 index := arr.Index(value) 223 if index != -1 { 224 e, err = arr.Remove(index) 225 } 226 return 227 } 228 229 // Clear array 230 func (arr *Array) Clear() { 231 arr.data = make([]interface{}, arr.size) 232 arr.size = 0 233 } 234 235 // Raw original array 236 func (arr *Array) Raw() []interface{} { 237 v := make([]interface{}, arr.size) 238 copy(v, arr.data) 239 return v 240 } 241 242 // Format output sequence 243 func (arr *Array) Format() (format string) { 244 format = fmt.Sprintf("Array: size = %d , capacity = %d\n", arr.size, cap(arr.data)) 245 format += "[" 246 for i := 0; i < arr.Length(); i++ { 247 format += fmt.Sprintf("%+v", arr.data[i]) 248 if i != arr.size-1 { 249 format += ", " 250 } 251 } 252 format += "]" 253 return 254 } 255 256 // Shuffle creates an slice of shuffled values 257 func (arr *Array) Shuffle() (array *Array) { 258 data := arr.Raw() 259 rand.Shuffle(len(data), func(i, j int) { 260 data[i], data[j] = data[j], data[i] 261 }) 262 array, _ = Copy(data) 263 return 264 } 265 266 // GetInf Get the element corresponding to the index position of [] interface {} 267 func GetInf(arr []interface{}, index int, def ...interface{}) (value interface{}, err error) { 268 arrLen := len(arr) 269 if arrLen > 0 && index < arrLen { 270 value = arr[index] 271 } else { 272 err = ErrIllegalIndex 273 var dValue interface{} 274 if len(def) > 0 { 275 dValue = def[0] 276 } 277 value = dValue 278 } 279 return 280 }