array.go raw

   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