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