github.com/gogf/gf@v1.16.9/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/gogf/gf.
     6  
     7  package garray
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"github.com/gogf/gf/errors/gcode"
    13  	"github.com/gogf/gf/errors/gerror"
    14  	"github.com/gogf/gf/internal/json"
    15  	"math"
    16  	"sort"
    17  
    18  	"github.com/gogf/gf/internal/rwmutex"
    19  	"github.com/gogf/gf/util/gconv"
    20  	"github.com/gogf/gf/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 a 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, (end-start+1)/step)
    55  	index := 0
    56  	for i := start; i <= end; i += step {
    57  		slice[index] = 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 `value` to the front of `index`.
   172  func (a *IntArray) InsertBefore(index int, value int) error {
   173  	a.mu.Lock()
   174  	defer a.mu.Unlock()
   175  	if index < 0 || index >= len(a.array) {
   176  		return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", index, len(a.array))
   177  	}
   178  	rear := append([]int{}, a.array[index:]...)
   179  	a.array = append(a.array[0:index], value)
   180  	a.array = append(a.array, rear...)
   181  	return nil
   182  }
   183  
   184  // InsertAfter inserts the `value` to the back of `index`.
   185  func (a *IntArray) InsertAfter(index int, value int) error {
   186  	a.mu.Lock()
   187  	defer a.mu.Unlock()
   188  	if index < 0 || index >= len(a.array) {
   189  		return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", index, len(a.array))
   190  	}
   191  	rear := append([]int{}, a.array[index+1:]...)
   192  	a.array = append(a.array[0:index+1], value)
   193  	a.array = append(a.array, rear...)
   194  	return nil
   195  }
   196  
   197  // Remove removes an item by index.
   198  // If the given `index` is out of range of the array, the `found` is false.
   199  func (a *IntArray) Remove(index int) (value int, found bool) {
   200  	a.mu.Lock()
   201  	defer a.mu.Unlock()
   202  	return a.doRemoveWithoutLock(index)
   203  }
   204  
   205  // doRemoveWithoutLock removes an item by index without lock.
   206  func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) {
   207  	if index < 0 || index >= len(a.array) {
   208  		return 0, false
   209  	}
   210  	// Determine array boundaries when deleting to improve deletion efficiency.
   211  	if index == 0 {
   212  		value := a.array[0]
   213  		a.array = a.array[1:]
   214  		return value, true
   215  	} else if index == len(a.array)-1 {
   216  		value := a.array[index]
   217  		a.array = a.array[:index]
   218  		return value, true
   219  	}
   220  	// If it is a non-boundary delete,
   221  	// it will involve the creation of an array,
   222  	// then the deletion is less efficient.
   223  	value = a.array[index]
   224  	a.array = append(a.array[:index], a.array[index+1:]...)
   225  	return value, true
   226  }
   227  
   228  // RemoveValue removes an item by value.
   229  // It returns true if value is found in the array, or else false if not found.
   230  func (a *IntArray) RemoveValue(value int) bool {
   231  	if i := a.Search(value); i != -1 {
   232  		_, found := a.Remove(i)
   233  		return found
   234  	}
   235  	return false
   236  }
   237  
   238  // PushLeft pushes one or multiple items to the beginning of array.
   239  func (a *IntArray) PushLeft(value ...int) *IntArray {
   240  	a.mu.Lock()
   241  	a.array = append(value, a.array...)
   242  	a.mu.Unlock()
   243  	return a
   244  }
   245  
   246  // PushRight pushes one or multiple items to the end of array.
   247  // It equals to Append.
   248  func (a *IntArray) PushRight(value ...int) *IntArray {
   249  	a.mu.Lock()
   250  	a.array = append(a.array, value...)
   251  	a.mu.Unlock()
   252  	return a
   253  }
   254  
   255  // PopLeft pops and returns an item from the beginning of array.
   256  // Note that if the array is empty, the `found` is false.
   257  func (a *IntArray) PopLeft() (value int, found bool) {
   258  	a.mu.Lock()
   259  	defer a.mu.Unlock()
   260  	if len(a.array) == 0 {
   261  		return 0, false
   262  	}
   263  	value = a.array[0]
   264  	a.array = a.array[1:]
   265  	return value, true
   266  }
   267  
   268  // PopRight pops and returns an item from the end of array.
   269  // Note that if the array is empty, the `found` is false.
   270  func (a *IntArray) PopRight() (value int, found bool) {
   271  	a.mu.Lock()
   272  	defer a.mu.Unlock()
   273  	index := len(a.array) - 1
   274  	if index < 0 {
   275  		return 0, false
   276  	}
   277  	value = a.array[index]
   278  	a.array = a.array[:index]
   279  	return value, true
   280  }
   281  
   282  // PopRand randomly pops and return an item out of array.
   283  // Note that if the array is empty, the `found` is false.
   284  func (a *IntArray) PopRand() (value int, found bool) {
   285  	a.mu.Lock()
   286  	defer a.mu.Unlock()
   287  	return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
   288  }
   289  
   290  // PopRands randomly pops and returns `size` items out of array.
   291  // If the given `size` is greater than size of the array, it returns all elements of the array.
   292  // Note that if given `size` <= 0 or the array is empty, it returns nil.
   293  func (a *IntArray) PopRands(size int) []int {
   294  	a.mu.Lock()
   295  	defer a.mu.Unlock()
   296  	if size <= 0 || len(a.array) == 0 {
   297  		return nil
   298  	}
   299  	if size >= len(a.array) {
   300  		size = len(a.array)
   301  	}
   302  	array := make([]int, size)
   303  	for i := 0; i < size; i++ {
   304  		array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
   305  	}
   306  	return array
   307  }
   308  
   309  // PopLefts pops and returns `size` items from the beginning of array.
   310  // If the given `size` is greater than size of the array, it returns all elements of the array.
   311  // Note that if given `size` <= 0 or the array is empty, it returns nil.
   312  func (a *IntArray) PopLefts(size int) []int {
   313  	a.mu.Lock()
   314  	defer a.mu.Unlock()
   315  	if size <= 0 || len(a.array) == 0 {
   316  		return nil
   317  	}
   318  	if size >= len(a.array) {
   319  		array := a.array
   320  		a.array = a.array[:0]
   321  		return array
   322  	}
   323  	value := a.array[0:size]
   324  	a.array = a.array[size:]
   325  	return value
   326  }
   327  
   328  // PopRights pops and returns `size` items from the end of array.
   329  // If the given `size` is greater than size of the array, it returns all elements of the array.
   330  // Note that if given `size` <= 0 or the array is empty, it returns nil.
   331  func (a *IntArray) PopRights(size int) []int {
   332  	a.mu.Lock()
   333  	defer a.mu.Unlock()
   334  	if size <= 0 || len(a.array) == 0 {
   335  		return nil
   336  	}
   337  	index := len(a.array) - size
   338  	if index <= 0 {
   339  		array := a.array
   340  		a.array = a.array[:0]
   341  		return array
   342  	}
   343  	value := a.array[index:]
   344  	a.array = a.array[:index]
   345  	return value
   346  }
   347  
   348  // Range picks and returns items by range, like array[start:end].
   349  // Notice, if in concurrent-safe usage, it returns a copy of slice;
   350  // else a pointer to the underlying data.
   351  //
   352  // If `end` is negative, then the offset will start from the end of array.
   353  // If `end` is omitted, then the sequence will have everything from start up
   354  // until the end of the array.
   355  func (a *IntArray) Range(start int, end ...int) []int {
   356  	a.mu.RLock()
   357  	defer a.mu.RUnlock()
   358  	offsetEnd := len(a.array)
   359  	if len(end) > 0 && end[0] < offsetEnd {
   360  		offsetEnd = end[0]
   361  	}
   362  	if start > offsetEnd {
   363  		return nil
   364  	}
   365  	if start < 0 {
   366  		start = 0
   367  	}
   368  	array := ([]int)(nil)
   369  	if a.mu.IsSafe() {
   370  		array = make([]int, offsetEnd-start)
   371  		copy(array, a.array[start:offsetEnd])
   372  	} else {
   373  		array = a.array[start:offsetEnd]
   374  	}
   375  	return array
   376  }
   377  
   378  // SubSlice returns a slice of elements from the array as specified
   379  // by the `offset` and `size` parameters.
   380  // If in concurrent safe usage, it returns a copy of the slice; else a pointer.
   381  //
   382  // If offset is non-negative, the sequence will start at that offset in the array.
   383  // If offset is negative, the sequence will start that far from the end of the array.
   384  //
   385  // If length is given and is positive, then the sequence will have up to that many elements in it.
   386  // If the array is shorter than the length, then only the available array elements will be present.
   387  // If length is given and is negative then the sequence will stop that many elements from the end of the array.
   388  // If it is omitted, then the sequence will have everything from offset up until the end of the array.
   389  //
   390  // Any possibility crossing the left border of array, it will fail.
   391  func (a *IntArray) SubSlice(offset int, length ...int) []int {
   392  	a.mu.RLock()
   393  	defer a.mu.RUnlock()
   394  	size := len(a.array)
   395  	if len(length) > 0 {
   396  		size = length[0]
   397  	}
   398  	if offset > len(a.array) {
   399  		return nil
   400  	}
   401  	if offset < 0 {
   402  		offset = len(a.array) + offset
   403  		if offset < 0 {
   404  			return nil
   405  		}
   406  	}
   407  	if size < 0 {
   408  		offset += size
   409  		size = -size
   410  		if offset < 0 {
   411  			return nil
   412  		}
   413  	}
   414  	end := offset + size
   415  	if end > len(a.array) {
   416  		end = len(a.array)
   417  		size = len(a.array) - offset
   418  	}
   419  	if a.mu.IsSafe() {
   420  		s := make([]int, size)
   421  		copy(s, a.array[offset:])
   422  		return s
   423  	} else {
   424  		return a.array[offset:end]
   425  	}
   426  }
   427  
   428  // Append is alias of PushRight,please See PushRight.
   429  func (a *IntArray) Append(value ...int) *IntArray {
   430  	a.mu.Lock()
   431  	a.array = append(a.array, value...)
   432  	a.mu.Unlock()
   433  	return a
   434  }
   435  
   436  // Len returns the length of array.
   437  func (a *IntArray) Len() int {
   438  	a.mu.RLock()
   439  	length := len(a.array)
   440  	a.mu.RUnlock()
   441  	return length
   442  }
   443  
   444  // Slice returns the underlying data of array.
   445  // Note that, if it's in concurrent-safe usage, it returns a copy of underlying data,
   446  // or else a pointer to the underlying data.
   447  func (a *IntArray) Slice() []int {
   448  	array := ([]int)(nil)
   449  	if a.mu.IsSafe() {
   450  		a.mu.RLock()
   451  		defer a.mu.RUnlock()
   452  		array = make([]int, len(a.array))
   453  		copy(array, a.array)
   454  	} else {
   455  		array = a.array
   456  	}
   457  	return array
   458  }
   459  
   460  // Interfaces returns current array as []interface{}.
   461  func (a *IntArray) Interfaces() []interface{} {
   462  	a.mu.RLock()
   463  	defer a.mu.RUnlock()
   464  	array := make([]interface{}, len(a.array))
   465  	for k, v := range a.array {
   466  		array[k] = v
   467  	}
   468  	return array
   469  }
   470  
   471  // Clone returns a new array, which is a copy of current array.
   472  func (a *IntArray) Clone() (newArray *IntArray) {
   473  	a.mu.RLock()
   474  	array := make([]int, len(a.array))
   475  	copy(array, a.array)
   476  	a.mu.RUnlock()
   477  	return NewIntArrayFrom(array, a.mu.IsSafe())
   478  }
   479  
   480  // Clear deletes all items of current array.
   481  func (a *IntArray) Clear() *IntArray {
   482  	a.mu.Lock()
   483  	if len(a.array) > 0 {
   484  		a.array = make([]int, 0)
   485  	}
   486  	a.mu.Unlock()
   487  	return a
   488  }
   489  
   490  // Contains checks whether a value exists in the array.
   491  func (a *IntArray) Contains(value int) bool {
   492  	return a.Search(value) != -1
   493  }
   494  
   495  // Search searches array by `value`, returns the index of `value`,
   496  // or returns -1 if not exists.
   497  func (a *IntArray) Search(value int) int {
   498  	a.mu.RLock()
   499  	defer a.mu.RUnlock()
   500  	if len(a.array) == 0 {
   501  		return -1
   502  	}
   503  	result := -1
   504  	for index, v := range a.array {
   505  		if v == value {
   506  			result = index
   507  			break
   508  		}
   509  	}
   510  	return result
   511  }
   512  
   513  // Unique uniques the array, clear repeated items.
   514  // Example: [1,1,2,3,2] -> [1,2,3]
   515  func (a *IntArray) Unique() *IntArray {
   516  	a.mu.Lock()
   517  	for i := 0; i < len(a.array)-1; i++ {
   518  		for j := i + 1; j < len(a.array); {
   519  			if a.array[i] == a.array[j] {
   520  				a.array = append(a.array[:j], a.array[j+1:]...)
   521  			} else {
   522  				j++
   523  			}
   524  		}
   525  	}
   526  	a.mu.Unlock()
   527  	return a
   528  }
   529  
   530  // LockFunc locks writing by callback function `f`.
   531  func (a *IntArray) LockFunc(f func(array []int)) *IntArray {
   532  	a.mu.Lock()
   533  	defer a.mu.Unlock()
   534  	f(a.array)
   535  	return a
   536  }
   537  
   538  // RLockFunc locks reading by callback function `f`.
   539  func (a *IntArray) RLockFunc(f func(array []int)) *IntArray {
   540  	a.mu.RLock()
   541  	defer a.mu.RUnlock()
   542  	f(a.array)
   543  	return a
   544  }
   545  
   546  // Merge merges `array` into current array.
   547  // The parameter `array` can be any garray or slice type.
   548  // The difference between Merge and Append is Append supports only specified slice type,
   549  // but Merge supports more parameter types.
   550  func (a *IntArray) Merge(array interface{}) *IntArray {
   551  	return a.Append(gconv.Ints(array)...)
   552  }
   553  
   554  // Fill fills an array with num entries of the value `value`,
   555  // keys starting at the `startIndex` parameter.
   556  func (a *IntArray) Fill(startIndex int, num int, value int) error {
   557  	a.mu.Lock()
   558  	defer a.mu.Unlock()
   559  	if startIndex < 0 || startIndex > len(a.array) {
   560  		return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", startIndex, len(a.array))
   561  	}
   562  	for i := startIndex; i < startIndex+num; i++ {
   563  		if i > len(a.array)-1 {
   564  			a.array = append(a.array, value)
   565  		} else {
   566  			a.array[i] = value
   567  		}
   568  	}
   569  	return nil
   570  }
   571  
   572  // Chunk splits an array into multiple arrays,
   573  // the size of each array is determined by `size`.
   574  // The last chunk may contain less than size elements.
   575  func (a *IntArray) Chunk(size int) [][]int {
   576  	if size < 1 {
   577  		return nil
   578  	}
   579  	a.mu.RLock()
   580  	defer a.mu.RUnlock()
   581  	length := len(a.array)
   582  	chunks := int(math.Ceil(float64(length) / float64(size)))
   583  	var n [][]int
   584  	for i, end := 0, 0; chunks > 0; chunks-- {
   585  		end = (i + 1) * size
   586  		if end > length {
   587  			end = length
   588  		}
   589  		n = append(n, a.array[i*size:end])
   590  		i++
   591  	}
   592  	return n
   593  }
   594  
   595  // Pad pads array to the specified length with `value`.
   596  // If size is positive then the array is padded on the right, or negative on the left.
   597  // If the absolute value of `size` is less than or equal to the length of the array
   598  // then no padding takes place.
   599  func (a *IntArray) Pad(size int, value int) *IntArray {
   600  	a.mu.Lock()
   601  	defer a.mu.Unlock()
   602  	if size == 0 || (size > 0 && size < len(a.array)) || (size < 0 && size > -len(a.array)) {
   603  		return a
   604  	}
   605  	n := size
   606  	if size < 0 {
   607  		n = -size
   608  	}
   609  	n -= len(a.array)
   610  	tmp := make([]int, n)
   611  	for i := 0; i < n; i++ {
   612  		tmp[i] = value
   613  	}
   614  	if size > 0 {
   615  		a.array = append(a.array, tmp...)
   616  	} else {
   617  		a.array = append(tmp, a.array...)
   618  	}
   619  	return a
   620  }
   621  
   622  // Rand randomly returns one item from array(no deleting).
   623  func (a *IntArray) Rand() (value int, found bool) {
   624  	a.mu.RLock()
   625  	defer a.mu.RUnlock()
   626  	if len(a.array) == 0 {
   627  		return 0, false
   628  	}
   629  	return a.array[grand.Intn(len(a.array))], true
   630  }
   631  
   632  // Rands randomly returns `size` items from array(no deleting).
   633  func (a *IntArray) Rands(size int) []int {
   634  	a.mu.RLock()
   635  	defer a.mu.RUnlock()
   636  	if size <= 0 || len(a.array) == 0 {
   637  		return nil
   638  	}
   639  	array := make([]int, size)
   640  	for i := 0; i < size; i++ {
   641  		array[i] = a.array[grand.Intn(len(a.array))]
   642  	}
   643  	return array
   644  }
   645  
   646  // Shuffle randomly shuffles the array.
   647  func (a *IntArray) Shuffle() *IntArray {
   648  	a.mu.Lock()
   649  	defer a.mu.Unlock()
   650  	for i, v := range grand.Perm(len(a.array)) {
   651  		a.array[i], a.array[v] = a.array[v], a.array[i]
   652  	}
   653  	return a
   654  }
   655  
   656  // Reverse makes array with elements in reverse order.
   657  func (a *IntArray) Reverse() *IntArray {
   658  	a.mu.Lock()
   659  	defer a.mu.Unlock()
   660  	for i, j := 0, len(a.array)-1; i < j; i, j = i+1, j-1 {
   661  		a.array[i], a.array[j] = a.array[j], a.array[i]
   662  	}
   663  	return a
   664  }
   665  
   666  // Join joins array elements with a string `glue`.
   667  func (a *IntArray) Join(glue string) string {
   668  	a.mu.RLock()
   669  	defer a.mu.RUnlock()
   670  	if len(a.array) == 0 {
   671  		return ""
   672  	}
   673  	buffer := bytes.NewBuffer(nil)
   674  	for k, v := range a.array {
   675  		buffer.WriteString(gconv.String(v))
   676  		if k != len(a.array)-1 {
   677  			buffer.WriteString(glue)
   678  		}
   679  	}
   680  	return buffer.String()
   681  }
   682  
   683  // CountValues counts the number of occurrences of all values in the array.
   684  func (a *IntArray) CountValues() map[int]int {
   685  	m := make(map[int]int)
   686  	a.mu.RLock()
   687  	defer a.mu.RUnlock()
   688  	for _, v := range a.array {
   689  		m[v]++
   690  	}
   691  	return m
   692  }
   693  
   694  // Iterator is alias of IteratorAsc.
   695  func (a *IntArray) Iterator(f func(k int, v int) bool) {
   696  	a.IteratorAsc(f)
   697  }
   698  
   699  // IteratorAsc iterates the array readonly in ascending order with given callback function `f`.
   700  // If `f` returns true, then it continues iterating; or false to stop.
   701  func (a *IntArray) IteratorAsc(f func(k int, v int) bool) {
   702  	a.mu.RLock()
   703  	defer a.mu.RUnlock()
   704  	for k, v := range a.array {
   705  		if !f(k, v) {
   706  			break
   707  		}
   708  	}
   709  }
   710  
   711  // IteratorDesc iterates the array readonly in descending order with given callback function `f`.
   712  // If `f` returns true, then it continues iterating; or false to stop.
   713  func (a *IntArray) IteratorDesc(f func(k int, v int) bool) {
   714  	a.mu.RLock()
   715  	defer a.mu.RUnlock()
   716  	for i := len(a.array) - 1; i >= 0; i-- {
   717  		if !f(i, a.array[i]) {
   718  			break
   719  		}
   720  	}
   721  }
   722  
   723  // String returns current array as a string, which implements like json.Marshal does.
   724  func (a *IntArray) String() string {
   725  	return "[" + a.Join(",") + "]"
   726  }
   727  
   728  // MarshalJSON implements the interface MarshalJSON for json.Marshal.
   729  // Note that do not use pointer as its receiver here.
   730  func (a IntArray) MarshalJSON() ([]byte, error) {
   731  	a.mu.RLock()
   732  	defer a.mu.RUnlock()
   733  	return json.Marshal(a.array)
   734  }
   735  
   736  // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
   737  func (a *IntArray) UnmarshalJSON(b []byte) error {
   738  	if a.array == nil {
   739  		a.array = make([]int, 0)
   740  	}
   741  	a.mu.Lock()
   742  	defer a.mu.Unlock()
   743  	if err := json.UnmarshalUseNumber(b, &a.array); err != nil {
   744  		return err
   745  	}
   746  	return nil
   747  }
   748  
   749  // UnmarshalValue is an interface implement which sets any type of value for array.
   750  func (a *IntArray) UnmarshalValue(value interface{}) error {
   751  	a.mu.Lock()
   752  	defer a.mu.Unlock()
   753  	switch value.(type) {
   754  	case string, []byte:
   755  		return json.UnmarshalUseNumber(gconv.Bytes(value), &a.array)
   756  	default:
   757  		a.array = gconv.SliceInt(value)
   758  	}
   759  	return nil
   760  }
   761  
   762  // FilterEmpty removes all zero value of the array.
   763  func (a *IntArray) FilterEmpty() *IntArray {
   764  	a.mu.Lock()
   765  	defer a.mu.Unlock()
   766  	for i := 0; i < len(a.array); {
   767  		if a.array[i] == 0 {
   768  			a.array = append(a.array[:i], a.array[i+1:]...)
   769  		} else {
   770  			i++
   771  		}
   772  	}
   773  	return a
   774  }
   775  
   776  // Walk applies a user supplied function `f` to every item of array.
   777  func (a *IntArray) Walk(f func(value int) int) *IntArray {
   778  	a.mu.Lock()
   779  	defer a.mu.Unlock()
   780  	for i, v := range a.array {
   781  		a.array[i] = f(v)
   782  	}
   783  	return a
   784  }
   785  
   786  // IsEmpty checks whether the array is empty.
   787  func (a *IntArray) IsEmpty() bool {
   788  	return a.Len() == 0
   789  }