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  }