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