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