github.com/wangyougui/gf/v2@v2.6.5/container/garray/garray_normal_int.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/wangyougui/gf.
     6  
     7  package garray
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"math"
    13  	"sort"
    14  
    15  	"github.com/wangyougui/gf/v2/errors/gcode"
    16  	"github.com/wangyougui/gf/v2/errors/gerror"
    17  	"github.com/wangyougui/gf/v2/internal/json"
    18  	"github.com/wangyougui/gf/v2/internal/rwmutex"
    19  	"github.com/wangyougui/gf/v2/util/gconv"
    20  	"github.com/wangyougui/gf/v2/util/grand"
    21  )
    22  
    23  // IntArray is a golang int array with rich features.
    24  // It contains a concurrent-safe/unsafe switch, which should be set
    25  // when its initialization and cannot be changed then.
    26  type IntArray struct {
    27  	mu    rwmutex.RWMutex
    28  	array []int
    29  }
    30  
    31  // NewIntArray creates and returns an empty array.
    32  // The parameter `safe` is used to specify whether using array in concurrent-safety,
    33  // which is false in default.
    34  func NewIntArray(safe ...bool) *IntArray {
    35  	return NewIntArraySize(0, 0, safe...)
    36  }
    37  
    38  // NewIntArraySize create and returns an array with given size and cap.
    39  // The parameter `safe` is used to specify whether using array in concurrent-safety,
    40  // which is false in default.
    41  func NewIntArraySize(size int, cap int, safe ...bool) *IntArray {
    42  	return &IntArray{
    43  		mu:    rwmutex.Create(safe...),
    44  		array: make([]int, size, cap),
    45  	}
    46  }
    47  
    48  // NewIntArrayRange creates and returns an array by a range from `start` to `end`
    49  // with step value `step`.
    50  func NewIntArrayRange(start, end, step int, safe ...bool) *IntArray {
    51  	if step == 0 {
    52  		panic(fmt.Sprintf(`invalid step value: %d`, step))
    53  	}
    54  	slice := make([]int, 0)
    55  	index := 0
    56  	for i := start; i <= end; i += step {
    57  		slice = append(slice, i)
    58  		index++
    59  	}
    60  	return NewIntArrayFrom(slice, safe...)
    61  }
    62  
    63  // NewIntArrayFrom creates and returns an array with given slice `array`.
    64  // The parameter `safe` is used to specify whether using array in concurrent-safety,
    65  // which is false in default.
    66  func NewIntArrayFrom(array []int, safe ...bool) *IntArray {
    67  	return &IntArray{
    68  		mu:    rwmutex.Create(safe...),
    69  		array: array,
    70  	}
    71  }
    72  
    73  // NewIntArrayFromCopy creates and returns an array from a copy of given slice `array`.
    74  // The parameter `safe` is used to specify whether using array in concurrent-safety,
    75  // which is false in default.
    76  func NewIntArrayFromCopy(array []int, safe ...bool) *IntArray {
    77  	newArray := make([]int, len(array))
    78  	copy(newArray, array)
    79  	return &IntArray{
    80  		mu:    rwmutex.Create(safe...),
    81  		array: newArray,
    82  	}
    83  }
    84  
    85  // At returns the value by the specified index.
    86  // If the given `index` is out of range of the array, it returns `0`.
    87  func (a *IntArray) At(index int) (value int) {
    88  	value, _ = a.Get(index)
    89  	return
    90  }
    91  
    92  // Get returns the value by the specified index.
    93  // If the given `index` is out of range of the array, the `found` is false.
    94  func (a *IntArray) Get(index int) (value int, found bool) {
    95  	a.mu.RLock()
    96  	defer a.mu.RUnlock()
    97  	if index < 0 || index >= len(a.array) {
    98  		return 0, false
    99  	}
   100  	return a.array[index], true
   101  }
   102  
   103  // Set sets value to specified index.
   104  func (a *IntArray) Set(index int, value int) error {
   105  	a.mu.Lock()
   106  	defer a.mu.Unlock()
   107  	if index < 0 || index >= len(a.array) {
   108  		return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", index, len(a.array))
   109  	}
   110  	a.array[index] = value
   111  	return nil
   112  }
   113  
   114  // SetArray sets the underlying slice array with the given `array`.
   115  func (a *IntArray) SetArray(array []int) *IntArray {
   116  	a.mu.Lock()
   117  	defer a.mu.Unlock()
   118  	a.array = array
   119  	return a
   120  }
   121  
   122  // Replace replaces the array items by given `array` from the beginning of array.
   123  func (a *IntArray) Replace(array []int) *IntArray {
   124  	a.mu.Lock()
   125  	defer a.mu.Unlock()
   126  	max := len(array)
   127  	if max > len(a.array) {
   128  		max = len(a.array)
   129  	}
   130  	for i := 0; i < max; i++ {
   131  		a.array[i] = array[i]
   132  	}
   133  	return a
   134  }
   135  
   136  // Sum returns the sum of values in an array.
   137  func (a *IntArray) Sum() (sum int) {
   138  	a.mu.RLock()
   139  	defer a.mu.RUnlock()
   140  	for _, v := range a.array {
   141  		sum += v
   142  	}
   143  	return
   144  }
   145  
   146  // Sort sorts the array in increasing order.
   147  // The parameter `reverse` controls whether sort in increasing order(default) or decreasing order.
   148  func (a *IntArray) Sort(reverse ...bool) *IntArray {
   149  	a.mu.Lock()
   150  	defer a.mu.Unlock()
   151  	if len(reverse) > 0 && reverse[0] {
   152  		sort.Slice(a.array, func(i, j int) bool {
   153  			return a.array[i] >= a.array[j]
   154  		})
   155  	} else {
   156  		sort.Ints(a.array)
   157  	}
   158  	return a
   159  }
   160  
   161  // SortFunc sorts the array by custom function `less`.
   162  func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray {
   163  	a.mu.Lock()
   164  	defer a.mu.Unlock()
   165  	sort.Slice(a.array, func(i, j int) bool {
   166  		return less(a.array[i], a.array[j])
   167  	})
   168  	return a
   169  }
   170  
   171  // InsertBefore inserts the `values` to the front of `index`.
   172  func (a *IntArray) InsertBefore(index int, values ...int) error {
   173  	a.mu.Lock()
   174  	defer a.mu.Unlock()
   175  	if index < 0 || index >= len(a.array) {
   176  		return gerror.NewCodef(
   177  			gcode.CodeInvalidParameter,
   178  			"index %d out of array range %d",
   179  			index, len(a.array),
   180  		)
   181  	}
   182  	rear := append([]int{}, a.array[index:]...)
   183  	a.array = append(a.array[0:index], values...)
   184  	a.array = append(a.array, rear...)
   185  	return nil
   186  }
   187  
   188  // InsertAfter inserts the `value` to the back of `index`.
   189  func (a *IntArray) InsertAfter(index int, values ...int) error {
   190  	a.mu.Lock()
   191  	defer a.mu.Unlock()
   192  	if index < 0 || index >= len(a.array) {
   193  		return gerror.NewCodef(
   194  			gcode.CodeInvalidParameter,
   195  			"index %d out of array range %d",
   196  			index, len(a.array),
   197  		)
   198  	}
   199  	rear := append([]int{}, a.array[index+1:]...)
   200  	a.array = append(a.array[0:index+1], values...)
   201  	a.array = append(a.array, rear...)
   202  	return nil
   203  }
   204  
   205  // Remove removes an item by index.
   206  // If the given `index` is out of range of the array, the `found` is false.
   207  func (a *IntArray) Remove(index int) (value int, found bool) {
   208  	a.mu.Lock()
   209  	defer a.mu.Unlock()
   210  	return a.doRemoveWithoutLock(index)
   211  }
   212  
   213  // doRemoveWithoutLock removes an item by index without lock.
   214  func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) {
   215  	if index < 0 || index >= len(a.array) {
   216  		return 0, false
   217  	}
   218  	// Determine array boundaries when deleting to improve deletion efficiency.
   219  	if index == 0 {
   220  		value := a.array[0]
   221  		a.array = a.array[1:]
   222  		return value, true
   223  	} else if index == len(a.array)-1 {
   224  		value := a.array[index]
   225  		a.array = a.array[:index]
   226  		return value, true
   227  	}
   228  	// If it is a non-boundary delete,
   229  	// it will involve the creation of an array,
   230  	// then the deletion is less efficient.
   231  	value = a.array[index]
   232  	a.array = append(a.array[:index], a.array[index+1:]...)
   233  	return value, true
   234  }
   235  
   236  // RemoveValue removes an item by value.
   237  // It returns true if value is found in the array, or else false if not found.
   238  func (a *IntArray) RemoveValue(value int) bool {
   239  	a.mu.Lock()
   240  	defer a.mu.Unlock()
   241  	if i := a.doSearchWithoutLock(value); i != -1 {
   242  		a.doRemoveWithoutLock(i)
   243  		return true
   244  	}
   245  	return false
   246  }
   247  
   248  // RemoveValues removes multiple items by `values`.
   249  func (a *IntArray) RemoveValues(values ...int) {
   250  	a.mu.Lock()
   251  	defer a.mu.Unlock()
   252  	for _, value := range values {
   253  		if i := a.doSearchWithoutLock(value); i != -1 {
   254  			a.doRemoveWithoutLock(i)
   255  		}
   256  	}
   257  }
   258  
   259  // PushLeft pushes one or multiple items to the beginning of array.
   260  func (a *IntArray) PushLeft(value ...int) *IntArray {
   261  	a.mu.Lock()
   262  	a.array = append(value, a.array...)
   263  	a.mu.Unlock()
   264  	return a
   265  }
   266  
   267  // PushRight pushes one or multiple items to the end of array.
   268  // It equals to Append.
   269  func (a *IntArray) PushRight(value ...int) *IntArray {
   270  	a.mu.Lock()
   271  	a.array = append(a.array, value...)
   272  	a.mu.Unlock()
   273  	return a
   274  }
   275  
   276  // PopLeft pops and returns an item from the beginning of array.
   277  // Note that if the array is empty, the `found` is false.
   278  func (a *IntArray) PopLeft() (value int, found bool) {
   279  	a.mu.Lock()
   280  	defer a.mu.Unlock()
   281  	if len(a.array) == 0 {
   282  		return 0, false
   283  	}
   284  	value = a.array[0]
   285  	a.array = a.array[1:]
   286  	return value, true
   287  }
   288  
   289  // PopRight pops and returns an item from the end of array.
   290  // Note that if the array is empty, the `found` is false.
   291  func (a *IntArray) PopRight() (value int, found bool) {
   292  	a.mu.Lock()
   293  	defer a.mu.Unlock()
   294  	index := len(a.array) - 1
   295  	if index < 0 {
   296  		return 0, false
   297  	}
   298  	value = a.array[index]
   299  	a.array = a.array[:index]
   300  	return value, true
   301  }
   302  
   303  // PopRand randomly pops and return an item out of array.
   304  // Note that if the array is empty, the `found` is false.
   305  func (a *IntArray) PopRand() (value int, found bool) {
   306  	a.mu.Lock()
   307  	defer a.mu.Unlock()
   308  	return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
   309  }
   310  
   311  // PopRands randomly pops and returns `size` items out of array.
   312  // If the given `size` is greater than size of the array, it returns all elements of the array.
   313  // Note that if given `size` <= 0 or the array is empty, it returns nil.
   314  func (a *IntArray) PopRands(size int) []int {
   315  	a.mu.Lock()
   316  	defer a.mu.Unlock()
   317  	if size <= 0 || len(a.array) == 0 {
   318  		return nil
   319  	}
   320  	if size >= len(a.array) {
   321  		size = len(a.array)
   322  	}
   323  	array := make([]int, size)
   324  	for i := 0; i < size; i++ {
   325  		array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
   326  	}
   327  	return array
   328  }
   329  
   330  // PopLefts pops and returns `size` items from the beginning of array.
   331  // If the given `size` is greater than size of the array, it returns all elements of the array.
   332  // Note that if given `size` <= 0 or the array is empty, it returns nil.
   333  func (a *IntArray) PopLefts(size int) []int {
   334  	a.mu.Lock()
   335  	defer a.mu.Unlock()
   336  	if size <= 0 || len(a.array) == 0 {
   337  		return nil
   338  	}
   339  	if size >= len(a.array) {
   340  		array := a.array
   341  		a.array = a.array[:0]
   342  		return array
   343  	}
   344  	value := a.array[0:size]
   345  	a.array = a.array[size:]
   346  	return value
   347  }
   348  
   349  // PopRights pops and returns `size` items from the end of array.
   350  // If the given `size` is greater than size of the array, it returns all elements of the array.
   351  // Note that if given `size` <= 0 or the array is empty, it returns nil.
   352  func (a *IntArray) PopRights(size int) []int {
   353  	a.mu.Lock()
   354  	defer a.mu.Unlock()
   355  	if size <= 0 || len(a.array) == 0 {
   356  		return nil
   357  	}
   358  	index := len(a.array) - size
   359  	if index <= 0 {
   360  		array := a.array
   361  		a.array = a.array[:0]
   362  		return array
   363  	}
   364  	value := a.array[index:]
   365  	a.array = a.array[:index]
   366  	return value
   367  }
   368  
   369  // Range picks and returns items by range, like array[start:end].
   370  // Notice, if in concurrent-safe usage, it returns a copy of slice;
   371  // else a pointer to the underlying data.
   372  //
   373  // If `end` is negative, then the offset will start from the end of array.
   374  // If `end` is omitted, then the sequence will have everything from start up
   375  // until the end of the array.
   376  func (a *IntArray) Range(start int, end ...int) []int {
   377  	a.mu.RLock()
   378  	defer a.mu.RUnlock()
   379  	offsetEnd := len(a.array)
   380  	if len(end) > 0 && end[0] < offsetEnd {
   381  		offsetEnd = end[0]
   382  	}
   383  	if start > offsetEnd {
   384  		return nil
   385  	}
   386  	if start < 0 {
   387  		start = 0
   388  	}
   389  	array := ([]int)(nil)
   390  	if a.mu.IsSafe() {
   391  		array = make([]int, offsetEnd-start)
   392  		copy(array, a.array[start:offsetEnd])
   393  	} else {
   394  		array = a.array[start:offsetEnd]
   395  	}
   396  	return array
   397  }
   398  
   399  // SubSlice returns a slice of elements from the array as specified
   400  // by the `offset` and `size` parameters.
   401  // If in concurrent safe usage, it returns a copy of the slice; else a pointer.
   402  //
   403  // If offset is non-negative, the sequence will start at that offset in the array.
   404  // If offset is negative, the sequence will start that far from the end of the array.
   405  //
   406  // If length is given and is positive, then the sequence will have up to that many elements in it.
   407  // If the array is shorter than the length, then only the available array elements will be present.
   408  // If length is given and is negative then the sequence will stop that many elements from the end of the array.
   409  // If it is omitted, then the sequence will have everything from offset up until the end of the array.
   410  //
   411  // Any possibility crossing the left border of array, it will fail.
   412  func (a *IntArray) SubSlice(offset int, length ...int) []int {
   413  	a.mu.RLock()
   414  	defer a.mu.RUnlock()
   415  	size := len(a.array)
   416  	if len(length) > 0 {
   417  		size = length[0]
   418  	}
   419  	if offset > len(a.array) {
   420  		return nil
   421  	}
   422  	if offset < 0 {
   423  		offset = len(a.array) + offset
   424  		if offset < 0 {
   425  			return nil
   426  		}
   427  	}
   428  	if size < 0 {
   429  		offset += size
   430  		size = -size
   431  		if offset < 0 {
   432  			return nil
   433  		}
   434  	}
   435  	end := offset + size
   436  	if end > len(a.array) {
   437  		end = len(a.array)
   438  		size = len(a.array) - offset
   439  	}
   440  	if a.mu.IsSafe() {
   441  		s := make([]int, size)
   442  		copy(s, a.array[offset:])
   443  		return s
   444  	} else {
   445  		return a.array[offset:end]
   446  	}
   447  }
   448  
   449  // Append is alias of PushRight,please See PushRight.
   450  func (a *IntArray) Append(value ...int) *IntArray {
   451  	a.mu.Lock()
   452  	a.array = append(a.array, value...)
   453  	a.mu.Unlock()
   454  	return a
   455  }
   456  
   457  // Len returns the length of array.
   458  func (a *IntArray) Len() int {
   459  	a.mu.RLock()
   460  	length := len(a.array)
   461  	a.mu.RUnlock()
   462  	return length
   463  }
   464  
   465  // Slice returns the underlying data of array.
   466  // Note that, if it's in concurrent-safe usage, it returns a copy of underlying data,
   467  // or else a pointer to the underlying data.
   468  func (a *IntArray) Slice() []int {
   469  	array := ([]int)(nil)
   470  	if a.mu.IsSafe() {
   471  		a.mu.RLock()
   472  		defer a.mu.RUnlock()
   473  		array = make([]int, len(a.array))
   474  		copy(array, a.array)
   475  	} else {
   476  		array = a.array
   477  	}
   478  	return array
   479  }
   480  
   481  // Interfaces returns current array as []interface{}.
   482  func (a *IntArray) Interfaces() []interface{} {
   483  	a.mu.RLock()
   484  	defer a.mu.RUnlock()
   485  	array := make([]interface{}, len(a.array))
   486  	for k, v := range a.array {
   487  		array[k] = v
   488  	}
   489  	return array
   490  }
   491  
   492  // Clone returns a new array, which is a copy of current array.
   493  func (a *IntArray) Clone() (newArray *IntArray) {
   494  	a.mu.RLock()
   495  	array := make([]int, len(a.array))
   496  	copy(array, a.array)
   497  	a.mu.RUnlock()
   498  	return NewIntArrayFrom(array, a.mu.IsSafe())
   499  }
   500  
   501  // Clear deletes all items of current array.
   502  func (a *IntArray) Clear() *IntArray {
   503  	a.mu.Lock()
   504  	if len(a.array) > 0 {
   505  		a.array = make([]int, 0)
   506  	}
   507  	a.mu.Unlock()
   508  	return a
   509  }
   510  
   511  // Contains checks whether a value exists in the array.
   512  func (a *IntArray) Contains(value int) bool {
   513  	return a.Search(value) != -1
   514  }
   515  
   516  // Search searches array by `value`, returns the index of `value`,
   517  // or returns -1 if not exists.
   518  func (a *IntArray) Search(value int) int {
   519  	a.mu.RLock()
   520  	defer a.mu.RUnlock()
   521  	return a.doSearchWithoutLock(value)
   522  }
   523  
   524  func (a *IntArray) doSearchWithoutLock(value int) int {
   525  	if len(a.array) == 0 {
   526  		return -1
   527  	}
   528  	result := -1
   529  	for index, v := range a.array {
   530  		if v == value {
   531  			result = index
   532  			break
   533  		}
   534  	}
   535  	return result
   536  }
   537  
   538  // Unique uniques the array, clear repeated items.
   539  // Example: [1,1,2,3,2] -> [1,2,3]
   540  func (a *IntArray) Unique() *IntArray {
   541  	a.mu.Lock()
   542  	defer a.mu.Unlock()
   543  	if len(a.array) == 0 {
   544  		return a
   545  	}
   546  	var (
   547  		ok          bool
   548  		temp        int
   549  		uniqueSet   = make(map[int]struct{})
   550  		uniqueArray = make([]int, 0, len(a.array))
   551  	)
   552  	for i := 0; i < len(a.array); i++ {
   553  		temp = a.array[i]
   554  		if _, ok = uniqueSet[temp]; ok {
   555  			continue
   556  		}
   557  		uniqueSet[temp] = struct{}{}
   558  		uniqueArray = append(uniqueArray, temp)
   559  	}
   560  	a.array = uniqueArray
   561  	return a
   562  }
   563  
   564  // LockFunc locks writing by callback function `f`.
   565  func (a *IntArray) LockFunc(f func(array []int)) *IntArray {
   566  	a.mu.Lock()
   567  	defer a.mu.Unlock()
   568  	f(a.array)
   569  	return a
   570  }
   571  
   572  // RLockFunc locks reading by callback function `f`.
   573  func (a *IntArray) RLockFunc(f func(array []int)) *IntArray {
   574  	a.mu.RLock()
   575  	defer a.mu.RUnlock()
   576  	f(a.array)
   577  	return a
   578  }
   579  
   580  // Merge merges `array` into current array.
   581  // The parameter `array` can be any garray or slice type.
   582  // The difference between Merge and Append is Append supports only specified slice type,
   583  // but Merge supports more parameter types.
   584  func (a *IntArray) Merge(array interface{}) *IntArray {
   585  	return a.Append(gconv.Ints(array)...)
   586  }
   587  
   588  // Fill fills an array with num entries of the value `value`,
   589  // keys starting at the `startIndex` parameter.
   590  func (a *IntArray) Fill(startIndex int, num int, value int) error {
   591  	a.mu.Lock()
   592  	defer a.mu.Unlock()
   593  	if startIndex < 0 || startIndex > len(a.array) {
   594  		return gerror.NewCodef(
   595  			gcode.CodeInvalidParameter,
   596  			"index %d out of array range %d",
   597  			startIndex, len(a.array),
   598  		)
   599  	}
   600  	for i := startIndex; i < startIndex+num; i++ {
   601  		if i > len(a.array)-1 {
   602  			a.array = append(a.array, value)
   603  		} else {
   604  			a.array[i] = value
   605  		}
   606  	}
   607  	return nil
   608  }
   609  
   610  // Chunk splits an array into multiple arrays,
   611  // the size of each array is determined by `size`.
   612  // The last chunk may contain less than size elements.
   613  func (a *IntArray) Chunk(size int) [][]int {
   614  	if size < 1 {
   615  		return nil
   616  	}
   617  	a.mu.RLock()
   618  	defer a.mu.RUnlock()
   619  	length := len(a.array)
   620  	chunks := int(math.Ceil(float64(length) / float64(size)))
   621  	var n [][]int
   622  	for i, end := 0, 0; chunks > 0; chunks-- {
   623  		end = (i + 1) * size
   624  		if end > length {
   625  			end = length
   626  		}
   627  		n = append(n, a.array[i*size:end])
   628  		i++
   629  	}
   630  	return n
   631  }
   632  
   633  // Pad pads array to the specified length with `value`.
   634  // If size is positive then the array is padded on the right, or negative on the left.
   635  // If the absolute value of `size` is less than or equal to the length of the array
   636  // then no padding takes place.
   637  func (a *IntArray) Pad(size int, value int) *IntArray {
   638  	a.mu.Lock()
   639  	defer a.mu.Unlock()
   640  	if size == 0 || (size > 0 && size < len(a.array)) || (size < 0 && size > -len(a.array)) {
   641  		return a
   642  	}
   643  	n := size
   644  	if size < 0 {
   645  		n = -size
   646  	}
   647  	n -= len(a.array)
   648  	tmp := make([]int, n)
   649  	for i := 0; i < n; i++ {
   650  		tmp[i] = value
   651  	}
   652  	if size > 0 {
   653  		a.array = append(a.array, tmp...)
   654  	} else {
   655  		a.array = append(tmp, a.array...)
   656  	}
   657  	return a
   658  }
   659  
   660  // Rand randomly returns one item from array(no deleting).
   661  func (a *IntArray) Rand() (value int, found bool) {
   662  	a.mu.RLock()
   663  	defer a.mu.RUnlock()
   664  	if len(a.array) == 0 {
   665  		return 0, false
   666  	}
   667  	return a.array[grand.Intn(len(a.array))], true
   668  }
   669  
   670  // Rands randomly returns `size` items from array(no deleting).
   671  func (a *IntArray) Rands(size int) []int {
   672  	a.mu.RLock()
   673  	defer a.mu.RUnlock()
   674  	if size <= 0 || len(a.array) == 0 {
   675  		return nil
   676  	}
   677  	array := make([]int, size)
   678  	for i := 0; i < size; i++ {
   679  		array[i] = a.array[grand.Intn(len(a.array))]
   680  	}
   681  	return array
   682  }
   683  
   684  // Shuffle randomly shuffles the array.
   685  func (a *IntArray) Shuffle() *IntArray {
   686  	a.mu.Lock()
   687  	defer a.mu.Unlock()
   688  	for i, v := range grand.Perm(len(a.array)) {
   689  		a.array[i], a.array[v] = a.array[v], a.array[i]
   690  	}
   691  	return a
   692  }
   693  
   694  // Reverse makes array with elements in reverse order.
   695  func (a *IntArray) Reverse() *IntArray {
   696  	a.mu.Lock()
   697  	defer a.mu.Unlock()
   698  	for i, j := 0, len(a.array)-1; i < j; i, j = i+1, j-1 {
   699  		a.array[i], a.array[j] = a.array[j], a.array[i]
   700  	}
   701  	return a
   702  }
   703  
   704  // Join joins array elements with a string `glue`.
   705  func (a *IntArray) Join(glue string) string {
   706  	a.mu.RLock()
   707  	defer a.mu.RUnlock()
   708  	if len(a.array) == 0 {
   709  		return ""
   710  	}
   711  	buffer := bytes.NewBuffer(nil)
   712  	for k, v := range a.array {
   713  		buffer.WriteString(gconv.String(v))
   714  		if k != len(a.array)-1 {
   715  			buffer.WriteString(glue)
   716  		}
   717  	}
   718  	return buffer.String()
   719  }
   720  
   721  // CountValues counts the number of occurrences of all values in the array.
   722  func (a *IntArray) CountValues() map[int]int {
   723  	m := make(map[int]int)
   724  	a.mu.RLock()
   725  	defer a.mu.RUnlock()
   726  	for _, v := range a.array {
   727  		m[v]++
   728  	}
   729  	return m
   730  }
   731  
   732  // Iterator is alias of IteratorAsc.
   733  func (a *IntArray) Iterator(f func(k int, v int) bool) {
   734  	a.IteratorAsc(f)
   735  }
   736  
   737  // IteratorAsc iterates the array readonly in ascending order with given callback function `f`.
   738  // If `f` returns true, then it continues iterating; or false to stop.
   739  func (a *IntArray) IteratorAsc(f func(k int, v int) bool) {
   740  	a.mu.RLock()
   741  	defer a.mu.RUnlock()
   742  	for k, v := range a.array {
   743  		if !f(k, v) {
   744  			break
   745  		}
   746  	}
   747  }
   748  
   749  // IteratorDesc iterates the array readonly in descending order with given callback function `f`.
   750  // If `f` returns true, then it continues iterating; or false to stop.
   751  func (a *IntArray) IteratorDesc(f func(k int, v int) bool) {
   752  	a.mu.RLock()
   753  	defer a.mu.RUnlock()
   754  	for i := len(a.array) - 1; i >= 0; i-- {
   755  		if !f(i, a.array[i]) {
   756  			break
   757  		}
   758  	}
   759  }
   760  
   761  // String returns current array as a string, which implements like json.Marshal does.
   762  func (a *IntArray) String() string {
   763  	if a == nil {
   764  		return ""
   765  	}
   766  	return "[" + a.Join(",") + "]"
   767  }
   768  
   769  // MarshalJSON implements the interface MarshalJSON for json.Marshal.
   770  // Note that do not use pointer as its receiver here.
   771  func (a IntArray) MarshalJSON() ([]byte, error) {
   772  	a.mu.RLock()
   773  	defer a.mu.RUnlock()
   774  	return json.Marshal(a.array)
   775  }
   776  
   777  // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
   778  func (a *IntArray) UnmarshalJSON(b []byte) error {
   779  	if a.array == nil {
   780  		a.array = make([]int, 0)
   781  	}
   782  	a.mu.Lock()
   783  	defer a.mu.Unlock()
   784  	if err := json.UnmarshalUseNumber(b, &a.array); err != nil {
   785  		return err
   786  	}
   787  	return nil
   788  }
   789  
   790  // UnmarshalValue is an interface implement which sets any type of value for array.
   791  func (a *IntArray) UnmarshalValue(value interface{}) error {
   792  	a.mu.Lock()
   793  	defer a.mu.Unlock()
   794  	switch value.(type) {
   795  	case string, []byte:
   796  		return json.UnmarshalUseNumber(gconv.Bytes(value), &a.array)
   797  	default:
   798  		a.array = gconv.SliceInt(value)
   799  	}
   800  	return nil
   801  }
   802  
   803  // Filter iterates array and filters elements using custom callback function.
   804  // It removes the element from array if callback function `filter` returns true,
   805  // it or else does nothing and continues iterating.
   806  func (a *IntArray) Filter(filter func(index int, value int) bool) *IntArray {
   807  	a.mu.Lock()
   808  	defer a.mu.Unlock()
   809  	for i := 0; i < len(a.array); {
   810  		if filter(i, a.array[i]) {
   811  			a.array = append(a.array[:i], a.array[i+1:]...)
   812  		} else {
   813  			i++
   814  		}
   815  	}
   816  	return a
   817  }
   818  
   819  // FilterEmpty removes all zero value of the array.
   820  func (a *IntArray) FilterEmpty() *IntArray {
   821  	a.mu.Lock()
   822  	defer a.mu.Unlock()
   823  	for i := 0; i < len(a.array); {
   824  		if a.array[i] == 0 {
   825  			a.array = append(a.array[:i], a.array[i+1:]...)
   826  		} else {
   827  			i++
   828  		}
   829  	}
   830  	return a
   831  }
   832  
   833  // Walk applies a user supplied function `f` to every item of array.
   834  func (a *IntArray) Walk(f func(value int) int) *IntArray {
   835  	a.mu.Lock()
   836  	defer a.mu.Unlock()
   837  	for i, v := range a.array {
   838  		a.array[i] = f(v)
   839  	}
   840  	return a
   841  }
   842  
   843  // IsEmpty checks whether the array is empty.
   844  func (a *IntArray) IsEmpty() bool {
   845  	return a.Len() == 0
   846  }
   847  
   848  // DeepCopy implements interface for deep copy of current type.
   849  func (a *IntArray) DeepCopy() interface{} {
   850  	if a == nil {
   851  		return nil
   852  	}
   853  	a.mu.RLock()
   854  	defer a.mu.RUnlock()
   855  	newSlice := make([]int, len(a.array))
   856  	copy(newSlice, a.array)
   857  	return NewIntArrayFrom(newSlice, a.mu.IsSafe())
   858  }