1 package dara
2 3 import (
4 "fmt"
5 "reflect"
6 "sort"
7 "strings"
8 )
9 10 // ArrContains checks if an element is in the array
11 func ArrContains(arr interface{}, value interface{}) bool {
12 arrValue := reflect.ValueOf(arr)
13 valueValue := reflect.ValueOf(value)
14 15 // Ensure arr is a slice
16 if arrValue.Kind() != reflect.Slice {
17 return false
18 }
19 20 for i := 0; i < arrValue.Len(); i++ {
21 elem := arrValue.Index(i)
22 23 // Ensure the array element is a pointer
24 if elem.Kind() == reflect.Ptr {
25 if valueValue.Kind() == reflect.Ptr && elem.Pointer() == valueValue.Pointer() {
26 return true
27 }
28 if elem.Elem().Interface() == valueValue.Interface() {
29 return true
30 }
31 } else if elem.Kind() == reflect.Interface {
32 elem = elem.Elem()
33 if valueValue.Kind() == reflect.Ptr && elem.Interface() == valueValue.Pointer() {
34 return true
35 }
36 if elem.Interface() == valueValue.Interface() {
37 return true // Return the index if found
38 }
39 }
40 }
41 42 return false
43 }
44 45 // ArrIndex returns the index of the element in the array
46 func ArrIndex(arr interface{}, value interface{}) int {
47 arrValue := reflect.ValueOf(arr)
48 valueValue := reflect.ValueOf(value)
49 50 // Ensure arr is a slice
51 if arrValue.Kind() != reflect.Slice {
52 return -1
53 }
54 55 for i := 0; i < arrValue.Len(); i++ {
56 elem := arrValue.Index(i)
57 58 // Ensure the array element is a pointer
59 if elem.Kind() == reflect.Ptr {
60 // Dereference the pointer to get the underlying value
61 if valueValue.Kind() == reflect.Ptr && elem.Pointer() == valueValue.Pointer() {
62 return i
63 }
64 if elem.Elem().Interface() == valueValue.Interface() {
65 return i // Return the index if found
66 }
67 } else if elem.Kind() == reflect.Interface {
68 elem = elem.Elem()
69 if valueValue.Kind() == reflect.Ptr && elem.Interface() == valueValue.Pointer() {
70 return i
71 }
72 if elem.Interface() == valueValue.Interface() {
73 return i // Return the index if found
74 }
75 }
76 }
77 78 return -1 // Return -1 if not found
79 }
80 81 func handlePointer(elem reflect.Value) string {
82 if elem.IsNil() {
83 return "" // Skip nil pointers
84 }
85 86 // Dereference the pointer
87 elem = elem.Elem()
88 return handleValue(elem)
89 }
90 91 func handleValue(elem reflect.Value) string {
92 switch elem.Kind() {
93 case reflect.String:
94 return elem.String()
95 case reflect.Int:
96 return fmt.Sprintf("%d", elem.Interface())
97 case reflect.Float64:
98 return fmt.Sprintf("%f", elem.Interface())
99 case reflect.Bool:
100 return fmt.Sprintf("%t", elem.Interface())
101 default:
102 return "" // Skip unsupported types
103 }
104 }
105 106 func ArrJoin(arr interface{}, sep string) string {
107 var strSlice []string
108 var str string
109 110 arrValue := reflect.ValueOf(arr)
111 112 // Ensure arr is a slice
113 if arrValue.Kind() != reflect.Slice {
114 return ""
115 }
116 117 for i := 0; i < arrValue.Len(); i++ {
118 elem := arrValue.Index(i)
119 120 if elem.Kind() == reflect.Ptr {
121 str = handlePointer(elem)
122 } else if elem.Kind() == reflect.Interface {
123 str = handleValue(elem.Elem())
124 } else {
125 str = handleValue(elem)
126 }
127 128 if str != "" {
129 strSlice = append(strSlice, str)
130 }
131 }
132 133 return strings.Join(strSlice, sep)
134 }
135 136 // ArrShift removes the first element from the array
137 func ArrShift(arr interface{}) interface{} {
138 arrValue := reflect.ValueOf(arr)
139 140 // Ensure arr is a pointer to a slice
141 if arrValue.Kind() != reflect.Ptr || arrValue.Elem().Kind() != reflect.Slice {
142 return nil
143 }
144 145 // Get the slice from the pointer
146 sliceValue := arrValue.Elem()
147 148 // Ensure the slice is not empty
149 if sliceValue.Len() == 0 {
150 return nil
151 }
152 153 // Get the first element
154 firstElem := sliceValue.Index(0)
155 156 // Create a new slice with one less element
157 newArrValue := reflect.MakeSlice(sliceValue.Type(), sliceValue.Len()-1, sliceValue.Cap())
158 159 // Copy the elements after the first one to the new slice
160 reflect.Copy(newArrValue, sliceValue.Slice(1, sliceValue.Len()))
161 162 // Set the original slice to the new slice
163 sliceValue.Set(newArrValue)
164 165 // Return the removed first element
166 return firstElem.Interface()
167 }
168 169 // ArrPop removes the last element from the array
170 func ArrPop(arr interface{}) interface{} {
171 arrValue := reflect.ValueOf(arr)
172 173 // Ensure arr is a pointer to a slice
174 if arrValue.Kind() != reflect.Ptr || arrValue.Elem().Kind() != reflect.Slice {
175 return nil
176 }
177 178 // Get the slice from the pointer
179 sliceValue := arrValue.Elem()
180 181 // Ensure the slice is not empty
182 if sliceValue.Len() == 0 {
183 return nil
184 }
185 186 // Get the last element
187 lastIndex := sliceValue.Len() - 1
188 lastElem := sliceValue.Index(lastIndex)
189 190 // Create a new slice with one less element
191 newArrValue := reflect.MakeSlice(sliceValue.Type(), sliceValue.Len()-1, sliceValue.Cap()-1)
192 193 // Copy the elements before the last one to the new slice
194 reflect.Copy(newArrValue, sliceValue.Slice(0, lastIndex))
195 196 // Set the original slice to the new slice
197 sliceValue.Set(newArrValue)
198 199 // Return the removed last element
200 return lastElem.Interface()
201 }
202 203 // ArrUnshift adds an element to the beginning of the array
204 func ArrUnshift(arr interface{}, value interface{}) int {
205 arrValue := reflect.ValueOf(arr)
206 207 // Ensure arr is a pointer to a slice
208 if arrValue.Kind() != reflect.Ptr || arrValue.Elem().Kind() != reflect.Slice {
209 return 0
210 }
211 212 // Get the slice from the pointer
213 sliceValue := arrValue.Elem()
214 215 // Create a new slice with one additional element
216 newArrValue := reflect.MakeSlice(sliceValue.Type(), sliceValue.Len()+1, sliceValue.Cap()+1)
217 218 // Set the new element as the first element
219 newArrValue.Index(0).Set(reflect.ValueOf(value))
220 221 // Copy the old elements to the new slice, starting at index 1
222 reflect.Copy(newArrValue.Slice(1, newArrValue.Len()), sliceValue)
223 224 // Set the original slice to the new slice
225 sliceValue.Set(newArrValue)
226 227 // Return the new length of the slice
228 return newArrValue.Len()
229 }
230 231 // ArrPush adds an element to the end of the array
232 func ArrPush(arr interface{}, value interface{}) int {
233 arrValue := reflect.ValueOf(arr)
234 235 // Ensure arr is a pointer to a slice
236 if arrValue.Kind() != reflect.Ptr || arrValue.Elem().Kind() != reflect.Slice {
237 return 0
238 }
239 240 // Get the slice from the pointer
241 sliceValue := arrValue.Elem()
242 243 // Create a new slice with one additional element
244 newArrValue := reflect.MakeSlice(sliceValue.Type(), sliceValue.Len()+1, sliceValue.Cap()+1)
245 246 // Copy the old elements to the new slice
247 reflect.Copy(newArrValue, sliceValue)
248 249 // Set the new element as the last element
250 newArrValue.Index(sliceValue.Len()).Set(reflect.ValueOf(value))
251 252 // Set the original slice to the new slice
253 sliceValue.Set(newArrValue)
254 255 // Return the new length of the slice
256 return newArrValue.Len()
257 }
258 259 // ConcatArr concatenates two arrays
260 func ConcatArr(arr1 interface{}, arr2 interface{}) interface{} {
261 var result []interface{}
262 value1 := reflect.ValueOf(arr1)
263 value2 := reflect.ValueOf(arr2)
264 265 // 检查 arr1 和 arr2 是否为切片
266 if value1.Kind() != reflect.Slice || value2.Kind() != reflect.Slice {
267 panic("ConcatArr: both inputs must be slices")
268 }
269 270 // 如果两个切片的类型相同
271 if value1.Type() == value2.Type() {
272 // 创建一个新的切片,类型与输入切片相同
273 result := reflect.MakeSlice(value1.Type(), 0, value1.Len()+value2.Len())
274 275 // 复制第一个切片的元素
276 for i := 0; i < value1.Len(); i++ {
277 result = reflect.Append(result, value1.Index(i))
278 }
279 // 复制第二个切片的元素
280 for i := 0; i < value2.Len(); i++ {
281 result = reflect.Append(result, value2.Index(i))
282 }
283 return result.Interface() // 返回类型相同的切片
284 }
285 286 // 否则返回 []interface{}
287 for i := 0; i < value1.Len(); i++ {
288 result = append(result, value1.Index(i).Interface())
289 }
290 for i := 0; i < value2.Len(); i++ {
291 result = append(result, value2.Index(i).Interface())
292 }
293 return result
294 }
295 296 // ArrAppend inserts a new pointer at a specified index in a pointer array.
297 func ArrAppend(arr interface{}, value interface{}, index int) {
298 arrV := reflect.ValueOf(arr)
299 if arrV.Kind() != reflect.Ptr || arrV.Elem().Kind() != reflect.Slice {
300 return
301 }
302 303 sliceV := arrV.Elem()
304 305 if index < 0 || index > sliceV.Len() {
306 return
307 }
308 309 valueV := reflect.ValueOf(value)
310 311 // 创建一个容纳新值的切片
312 newSlice := reflect.Append(sliceV, reflect.Zero(sliceV.Type().Elem()))
313 reflect.Copy(newSlice.Slice(index+1, newSlice.Len()), newSlice.Slice(index, newSlice.Len()-1))
314 newSlice.Index(index).Set(valueV)
315 316 // 更新原始切片
317 sliceV.Set(newSlice)
318 return
319 }
320 321 // ArrRemove removes an element from the array
322 func ArrRemove(arr interface{}, value interface{}) {
323 arrValue := reflect.ValueOf(arr)
324 325 // Ensure arr is a pointer to a slice
326 if arrValue.Kind() != reflect.Ptr || arrValue.Elem().Kind() != reflect.Slice {
327 return
328 }
329 330 // Get the slice from the pointer
331 slice := arrValue.Elem()
332 index := ArrIndex(slice.Interface(), value)
333 // If index is found, remove the element at that index
334 if index != -1 {
335 // Remove the element at the specified index
336 newSlice := reflect.MakeSlice(slice.Type(), 0, slice.Len()-1)
337 338 // Copy elements before the index
339 newSlice = reflect.AppendSlice(slice.Slice(0, index), slice.Slice(index+1, slice.Len()))
340 // Set the new slice back to the original reference
341 slice.Set(newSlice)
342 }
343 }
344 345 func SortArr(arr interface{}, order string) interface{} {
346 v := reflect.ValueOf(arr)
347 if v.Kind() != reflect.Slice {
348 panic("SortArr: input must be a slice")
349 }
350 351 // 创建一个新的切片来存储排序结果
352 newSlice := reflect.MakeSlice(v.Type(), v.Len(), v.Cap())
353 for i := 0; i < v.Len(); i++ {
354 newSlice.Index(i).Set(v.Index(i))
355 }
356 357 order = strings.ToLower(order)
358 359 sort.SliceStable(newSlice.Interface(), func(i, j int) bool {
360 return compare(newSlice.Index(i), newSlice.Index(j), order)
361 })
362 363 return newSlice.Interface()
364 }
365 366 func compare(elemI, elemJ reflect.Value, order string) bool {
367 valI := reflect.Indirect(elemI)
368 valJ := reflect.Indirect(elemJ)
369 370 // 对interface{}类型处理实际类型
371 if elemI.Kind() == reflect.Interface {
372 valI = reflect.Indirect(elemI.Elem())
373 }
374 if elemJ.Kind() == reflect.Interface {
375 valJ = reflect.Indirect(elemJ.Elem())
376 }
377 378 if valI.Kind() != valJ.Kind() {
379 380 if order == "asc" {
381 return valI.Kind() < valJ.Kind()
382 }
383 return valI.Kind() > valJ.Kind()
384 385 }
386 387 switch kind := valI.Kind(); kind {
388 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
389 return compareNumbers(valI.Int(), valJ.Int(), order)
390 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
391 return compareNumbers(int64(valI.Uint()), int64(valJ.Uint()), order)
392 case reflect.Float32, reflect.Float64:
393 return compareNumbers(valI.Float(), valJ.Float(), order)
394 case reflect.String:
395 return compareStrings(valI.String(), valJ.String(), order)
396 case reflect.Struct:
397 return compareStructs(valI, valJ, order)
398 default:
399 panic("SortArr: unsupported element type")
400 }
401 }
402 403 func compareNumbers(a, b interface{}, order string) bool {
404 switch order {
405 case "asc":
406 return a.(int64) < b.(int64)
407 case "desc":
408 return a.(int64) > b.(int64)
409 default:
410 return a.(int64) > b.(int64)
411 }
412 }
413 414 func compareStrings(a, b string, order string) bool {
415 switch order {
416 case "asc":
417 return a < b
418 case "desc":
419 return a > b
420 default:
421 return a > b
422 }
423 }
424 425 func compareStructs(valI, valJ reflect.Value, order string) bool {
426 if valI.NumField() > 0 && valJ.NumField() > 0 {
427 fieldI := reflect.Indirect(valI.Field(0))
428 fieldJ := reflect.Indirect(valJ.Field(0))
429 if fieldI.Kind() == fieldJ.Kind() {
430 switch fieldI.Kind() {
431 case reflect.String:
432 return compareStrings(fieldI.String(), fieldJ.String(), order)
433 case reflect.Int:
434 return compareNumbers(fieldI.Int(), fieldJ.Int(), order)
435 }
436 }
437 }
438 return false
439 }
440