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