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