github.com/Aoi-hosizora/ahlib@v1.5.1-0.20230404072829-241b93cf91c7/xslice/xslice.go (about)

     1  package xslice
     2  
     3  import (
     4  	"math/rand"
     5  	"sort"
     6  	"time"
     7  )
     8  
     9  // Equaller represents an equality function for two interface{} values, is used in XXXWith methods.
    10  type Equaller func(i, j interface{}) bool
    11  
    12  // Lesser represents a less function for sort, see sort.Interface.
    13  type Lesser func(i, j interface{}) bool
    14  
    15  // defaultEqualler represents a default Equaller, it just checks equality by `==`.
    16  var defaultEqualler Equaller = func(i, j interface{}) bool {
    17  	return i == j
    18  }
    19  
    20  // ShuffleSelf shuffles the []interface{} slice, by modifying given slice directly.
    21  func ShuffleSelf(slice []interface{}) {
    22  	coreShuffle(checkInterfaceSliceParam(slice))
    23  }
    24  
    25  // Shuffle shuffles the []interface{} slice and returns the result.
    26  func Shuffle(slice []interface{}) []interface{} {
    27  	newSlice := cloneInterfaceSlice(slice)
    28  	coreShuffle(checkInterfaceSliceParam(newSlice))
    29  	return newSlice
    30  }
    31  
    32  // ShuffleSelfG shuffles the []T slice, by modifying given slice directly, is the generic function of ShuffleSelf.
    33  func ShuffleSelfG(slice interface{}) {
    34  	coreShuffle(checkSliceInterfaceParam(slice))
    35  }
    36  
    37  // ShuffleG shuffles the []T slice and returns the result, is the generic function of Shuffle.
    38  func ShuffleG(slice interface{}) interface{} {
    39  	newSlice := cloneSliceInterface(slice)
    40  	coreShuffle(checkSliceInterfaceParam(newSlice))
    41  	return newSlice
    42  }
    43  
    44  func init() {
    45  	// for coreShuffle
    46  	rand.Seed(time.Now().UnixNano())
    47  }
    48  
    49  // coreShuffle is the implementation for ShuffleSelf, Shuffle, ShuffleSelfG and ShuffleG.
    50  func coreShuffle(slice innerSlice) {
    51  	for i := slice.length() - 1; i > 0; i-- {
    52  		j := rand.Intn(i + 1)
    53  		itemI, itemJ := slice.get(i), slice.get(j)
    54  		slice.set(i, itemJ)
    55  		slice.set(j, itemI)
    56  	}
    57  }
    58  
    59  // ReverseSelf reverses the []interface{} slice, by modifying given slice directly.
    60  func ReverseSelf(slice []interface{}) {
    61  	coreReverse(checkInterfaceSliceParam(slice))
    62  }
    63  
    64  // Reverse reverses the []interface{} slice and returns the result.
    65  func Reverse(slice []interface{}) []interface{} {
    66  	newSlice := cloneInterfaceSlice(slice)
    67  	coreReverse(checkInterfaceSliceParam(newSlice))
    68  	return newSlice
    69  }
    70  
    71  // ReverseSelfG reverses the []T slice, by modifying given slice directly, is the generic function of ReverseSelf.
    72  func ReverseSelfG(slice interface{}) {
    73  	coreReverse(checkSliceInterfaceParam(slice))
    74  }
    75  
    76  // ReverseG reverses the []T slice and returns the result, is the generic function of Reverse.
    77  func ReverseG(slice interface{}) interface{} {
    78  	newSlice := cloneSliceInterface(slice)
    79  	coreReverse(checkSliceInterfaceParam(newSlice))
    80  	return newSlice
    81  }
    82  
    83  // coreReverse is the implementation for ReverseSelf Reverse, ReverseSelfG and ReverseG.
    84  func coreReverse(slice innerSlice) {
    85  	for i, j := 0, slice.length()-1; i < j; i, j = i+1, j-1 {
    86  		itemI, itemJ := slice.get(i), slice.get(j)
    87  		slice.set(i, itemJ)
    88  		slice.set(j, itemI)
    89  	}
    90  }
    91  
    92  // SortSelf sorts the []interface{} slice with less function, by modifying given slice directly.
    93  func SortSelf(slice []interface{}, less Lesser) {
    94  	coreSort(checkInterfaceSliceParam(slice), less, false)
    95  }
    96  
    97  // Sort sorts the []interface{} slice with less function and returns the result.
    98  func Sort(slice []interface{}, less Lesser) []interface{} {
    99  	newSlice := cloneInterfaceSlice(slice)
   100  	coreSort(checkInterfaceSliceParam(newSlice), less, false)
   101  	return newSlice
   102  }
   103  
   104  // SortSelfG sorts the []T slice with less function, by modifying given slice directly, is the generic function of SortSelf.
   105  func SortSelfG(slice interface{}, less Lesser) {
   106  	coreSort(checkSliceInterfaceParam(slice), less, false)
   107  }
   108  
   109  // SortG sorts the []T slice with less function and returns the result, is the generic function of Sort.
   110  func SortG(slice interface{}, less Lesser) interface{} {
   111  	newSlice := cloneSliceInterface(slice)
   112  	coreSort(checkSliceInterfaceParam(newSlice), less, false)
   113  	return newSlice
   114  }
   115  
   116  // StableSortSelf sorts the []interface{} slice in stable with less function, by modifying given slice directly.
   117  func StableSortSelf(slice []interface{}, less Lesser) {
   118  	coreSort(checkInterfaceSliceParam(slice), less, true)
   119  }
   120  
   121  // StableSort sorts the []interface{} slice in stable with less function and returns the result.
   122  func StableSort(slice []interface{}, less Lesser) []interface{} {
   123  	newSlice := cloneInterfaceSlice(slice)
   124  	coreSort(checkInterfaceSliceParam(newSlice), less, true)
   125  	return newSlice
   126  }
   127  
   128  // StableSortSelfG sorts the []T slice in stable with less function, by modifying given slice directly, is the generic function of StableSortSelf.
   129  func StableSortSelfG(slice interface{}, less Lesser) {
   130  	coreSort(checkSliceInterfaceParam(slice), less, true)
   131  }
   132  
   133  // StableSortG sorts the []T slice with in stable less function and returns the result, is the generic function of StableSort.
   134  func StableSortG(slice interface{}, less Lesser) interface{} {
   135  	newSlice := cloneSliceInterface(slice)
   136  	coreSort(checkSliceInterfaceParam(newSlice), less, true)
   137  	return newSlice
   138  }
   139  
   140  // coreSort is the implementation for SortSelf, Sort, StableSortSelf, StableSort, SortSelfG, SortG, StableSortSelfG and StableSortG, using sort.Slice and sort.SliceStable.
   141  func coreSort(slice innerSlice, less Lesser, stable bool) {
   142  	ss := &sortableSlice{slice: slice, less: less}
   143  	if stable {
   144  		sort.Stable(ss)
   145  	} else {
   146  		sort.Sort(ss)
   147  	}
   148  }
   149  
   150  // IndexOf returns the first index of value in the []interface{} slice.
   151  func IndexOf(slice []interface{}, value interface{}) int {
   152  	return coreIndexOf(checkInterfaceSliceParam(slice), value, defaultEqualler)
   153  }
   154  
   155  // IndexOfWith returns the first index of value in the []interface{} slice with Equaller.
   156  func IndexOfWith(slice []interface{}, value interface{}, equaller Equaller) int {
   157  	return coreIndexOf(checkInterfaceSliceParam(slice), value, equaller)
   158  }
   159  
   160  // IndexOfG returns the first index of value in the []T slice, is the generic function of IndexOf.
   161  func IndexOfG(slice interface{}, value interface{}) int {
   162  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   163  	return coreIndexOf(s, v, defaultEqualler)
   164  }
   165  
   166  // IndexOfWithG returns the first index of value in the []T slice with Equaller, is the generic function of IndexOfWith.
   167  func IndexOfWithG(slice interface{}, value interface{}, equaller Equaller) int {
   168  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   169  	return coreIndexOf(s, v, equaller)
   170  }
   171  
   172  // coreIndexOf is the implementation for IndexOf, IndexOfWith, IndexOfG and IndexOfWithG.
   173  func coreIndexOf(slice innerSlice, value interface{}, equaller Equaller) int {
   174  	length := slice.length()
   175  	for idx := 0; idx < length; idx++ {
   176  		item := slice.get(idx)
   177  		if equaller(item, value) {
   178  			return idx
   179  		}
   180  	}
   181  	return -1
   182  }
   183  
   184  // LastIndexOf returns the last index of value in the []interface{} slice.
   185  func LastIndexOf(slice []interface{}, value interface{}) int {
   186  	return coreLastIndexOf(checkInterfaceSliceParam(slice), value, defaultEqualler)
   187  }
   188  
   189  // LastIndexOfWith returns the last index of value in the []interface{} slice with Equaller.
   190  func LastIndexOfWith(slice []interface{}, value interface{}, equaller Equaller) int {
   191  	return coreLastIndexOf(checkInterfaceSliceParam(slice), value, equaller)
   192  }
   193  
   194  // LastIndexOfG returns the last index of value in the []T slice, is the generic function of IndexOf.
   195  func LastIndexOfG(slice interface{}, value interface{}) int {
   196  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   197  	return coreLastIndexOf(s, v, defaultEqualler)
   198  }
   199  
   200  // LastIndexOfWithG returns the last index of value in the []T slice with Equaller, is the generic function of IndexOfWith.
   201  func LastIndexOfWithG(slice interface{}, value interface{}, equaller Equaller) int {
   202  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   203  	return coreLastIndexOf(s, v, equaller)
   204  }
   205  
   206  // coreLastIndexOf is the implementation for LastIndexOf, LastIndexOfWith, LastIndexOfG and LastIndexOfWithG.
   207  func coreLastIndexOf(slice innerSlice, value interface{}, equaller Equaller) int {
   208  	for idx := slice.length() - 1; idx >= 0; idx-- {
   209  		item := slice.get(idx)
   210  		if equaller(item, value) {
   211  			return idx
   212  		}
   213  	}
   214  	return -1
   215  }
   216  
   217  // Contains returns true if value is in the []interface{} slice.
   218  func Contains(slice []interface{}, value interface{}) bool {
   219  	return coreContains(checkInterfaceSliceParam(slice), value, defaultEqualler)
   220  }
   221  
   222  // ContainsWith returns true if value is in the []interface{} slice with Equaller.
   223  func ContainsWith(slice []interface{}, value interface{}, equaller Equaller) bool {
   224  	return coreContains(checkInterfaceSliceParam(slice), value, equaller)
   225  }
   226  
   227  // ContainsG returns true if value is in the []T slice, is the generic function of Contains.
   228  func ContainsG(slice interface{}, value interface{}) bool {
   229  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   230  	return coreContains(s, v, defaultEqualler)
   231  }
   232  
   233  // ContainsWithG returns true if value is in the []T slice with Equaller, is the generic function of ContainsWith.
   234  func ContainsWithG(slice interface{}, value interface{}, equaller Equaller) bool {
   235  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   236  	return coreContains(s, v, equaller)
   237  }
   238  
   239  // coreContains is the implementation for Contains, ContainsWith, ContainsG and ContainsWithG.
   240  func coreContains(slice innerSlice, value interface{}, equaller Equaller) bool {
   241  	length := slice.length()
   242  	for idx := 0; idx < length; idx++ {
   243  		item := slice.get(idx)
   244  		if equaller(item, value) {
   245  			return true
   246  		}
   247  	}
   248  	return false
   249  }
   250  
   251  // Count returns the count of value in the []interface{} slice.
   252  func Count(slice []interface{}, value interface{}) int {
   253  	return coreCount(checkInterfaceSliceParam(slice), value, defaultEqualler)
   254  }
   255  
   256  // CountWith returns the count of value in the []interface{} slice with Equaller.
   257  func CountWith(slice []interface{}, value interface{}, equaller Equaller) int {
   258  	return coreCount(checkInterfaceSliceParam(slice), value, equaller)
   259  }
   260  
   261  // CountG returns the count of value in the []T slice, is the generic function of Count.
   262  func CountG(slice interface{}, value interface{}) int {
   263  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   264  	return coreCount(s, v, defaultEqualler)
   265  }
   266  
   267  // CountWithG returns the count of value in the []T slice with Equaller, is the generic function of CountWith.
   268  func CountWithG(slice interface{}, value interface{}, equaller Equaller) int {
   269  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   270  	return coreCount(s, v, equaller)
   271  }
   272  
   273  // coreCount is the implementation for Count, CountWith, CountG and CountWithG.
   274  func coreCount(slice innerSlice, value interface{}, equaller Equaller) int {
   275  	cnt := 0
   276  	length := slice.length()
   277  	for idx := 0; idx < length; idx++ {
   278  		item := slice.get(idx)
   279  		if equaller(item, value) {
   280  			cnt++
   281  		}
   282  	}
   283  	return cnt
   284  }
   285  
   286  // Insert inserts values into []interface{} slice at index position using a new slice space to store.
   287  func Insert(slice []interface{}, index int, values ...interface{}) []interface{} {
   288  	return coreInsert(checkInterfaceSliceParam(slice), checkInterfaceSliceParam(values), index, false).actual().([]interface{})
   289  }
   290  
   291  // InsertSelf inserts values into []interface{} slice at index position using the space of given slice.
   292  func InsertSelf(slice []interface{}, index int, values ...interface{}) []interface{} {
   293  	return coreInsert(checkInterfaceSliceParam(slice), checkInterfaceSliceParam(values), index, true).actual().([]interface{})
   294  }
   295  
   296  // InsertG inserts values into []T slice at index position using a new slice space to store, is the generic function of Insert.
   297  func InsertG(slice interface{}, index int, values ...interface{}) interface{} {
   298  	s, v := checkTwoSliceInterfaceParam(slice, cloneSliceInterfaceFromInterfaceSlice(values, slice))
   299  	return coreInsert(s, v, index, false).actual()
   300  }
   301  
   302  // InsertSelfG inserts values into []T slice at index position using the space of given slice, is the generic function of InsertSelf.
   303  func InsertSelfG(slice interface{}, index int, values ...interface{}) interface{} {
   304  	s, v := checkTwoSliceInterfaceParam(slice, cloneSliceInterfaceFromInterfaceSlice(values, slice))
   305  	return coreInsert(s, v, index, true).actual()
   306  }
   307  
   308  // coreInsert is the implementation for InsertSelf, Insert, InsertSelfG and InsertG.
   309  func coreInsert(slice, values innerSlice, index int, self bool) innerSlice {
   310  	if values.length() == 0 {
   311  		if self {
   312  			return slice
   313  		}
   314  		return cloneInnerSliceItems(slice, 0)
   315  	}
   316  	if self {
   317  		slice.insert(index, values)
   318  		return slice
   319  	}
   320  	newSlice := cloneInnerSliceItems(slice, values.length())
   321  	newSlice.insert(index, values)
   322  	return newSlice
   323  }
   324  
   325  // Delete deletes value from []interface{} slice in n times.
   326  func Delete(slice []interface{}, value interface{}, n int) []interface{} {
   327  	return coreDelete(checkInterfaceSliceParam(slice), value, n, defaultEqualler).actual().([]interface{})
   328  }
   329  
   330  // DeleteWith deletes value from []interface{} slice in n times with Equaller.
   331  func DeleteWith(slice []interface{}, value interface{}, n int, equaller Equaller) []interface{} {
   332  	return coreDelete(checkInterfaceSliceParam(slice), value, n, equaller).actual().([]interface{})
   333  }
   334  
   335  // DeleteG deletes value from []T slice in n times, is the generic function of Delete.
   336  func DeleteG(slice interface{}, value interface{}, n int) interface{} {
   337  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   338  	return coreDelete(s, v, n, defaultEqualler).actual()
   339  }
   340  
   341  // DeleteWithG deletes value from []T slice in n times with Equaller, is the generic function of DeleteWith.
   342  func DeleteWithG(slice interface{}, value interface{}, n int, equaller Equaller) interface{} {
   343  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   344  	return coreDelete(s, v, n, equaller).actual()
   345  }
   346  
   347  // DeleteAll deletes value from []interface{} slice in all.
   348  func DeleteAll(slice []interface{}, value interface{}) []interface{} {
   349  	return coreDelete(checkInterfaceSliceParam(slice), value, 0, defaultEqualler).actual().([]interface{})
   350  }
   351  
   352  // DeleteAllWith deletes value from []interface{} slice in all with Equaller.
   353  func DeleteAllWith(slice []interface{}, value interface{}, equaller Equaller) []interface{} {
   354  	return coreDelete(checkInterfaceSliceParam(slice), value, 0, equaller).actual().([]interface{})
   355  }
   356  
   357  // DeleteAllG deletes value from []T slice in all, is the generic function of DeleteAll.
   358  func DeleteAllG(slice interface{}, value interface{}) interface{} {
   359  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   360  	return coreDelete(s, v, 0, defaultEqualler).actual()
   361  }
   362  
   363  // DeleteAllWithG deletes value from []T slice in all with Equaller, is the generic function of DeleteAllWith.
   364  func DeleteAllWithG(slice interface{}, value interface{}, equaller Equaller) interface{} {
   365  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   366  	return coreDelete(s, v, 0, equaller).actual()
   367  }
   368  
   369  // coreDelete is the implementation for Delete, DeleteWith, DeleteAll, DeleteAllWith, DeleteG, DeleteWithG, DeleteAllG and DeleteAllWithG.
   370  func coreDelete(slice innerSlice, value interface{}, n int, equaller Equaller) innerSlice {
   371  	length := slice.length()
   372  	if n <= 0 {
   373  		n = length
   374  	}
   375  	out := makeSameTypeInnerSlice(slice, 0, 0)
   376  	cnt := 0
   377  	for idx := 0; idx < length; idx++ { // O(n)
   378  		if cnt >= n {
   379  			for idx2 := idx; idx2 < length; idx2++ {
   380  				out.append(slice.get(idx2))
   381  			}
   382  			break
   383  		}
   384  		item := slice.get(idx)
   385  		if equaller(item, value) {
   386  			cnt++
   387  		} else {
   388  			out.append(item)
   389  		}
   390  	}
   391  	return out
   392  }
   393  
   394  // DeleteSelf deletes value from []interface{} slice in n times, by modifying given slice directly.
   395  func DeleteSelf(slice []interface{}, value interface{}, n int) []interface{} {
   396  	return coreDeleteSelf(checkInterfaceSliceParam(slice), value, n, defaultEqualler).actual().([]interface{})
   397  }
   398  
   399  // DeleteSelfWith deletes value from []interface{} slice in n times with Equaller, by modifying given slice directly.
   400  func DeleteSelfWith(slice []interface{}, value interface{}, n int, equaller Equaller) []interface{} {
   401  	return coreDeleteSelf(checkInterfaceSliceParam(slice), value, n, equaller).actual().([]interface{})
   402  }
   403  
   404  // DeleteSelfG deletes value from []T slice in n times, by modifying given slice directly, is the generic function of DeleteSelf.
   405  func DeleteSelfG(slice interface{}, value interface{}, n int) interface{} {
   406  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   407  	return coreDeleteSelf(s, v, n, defaultEqualler).actual()
   408  }
   409  
   410  // DeleteSelfWithG deletes value from []T slice in n times with Equaller, by modifying given slice directly, is the generic function of DeleteSelfWith.
   411  func DeleteSelfWithG(slice interface{}, value interface{}, n int, equaller Equaller) interface{} {
   412  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   413  	return coreDeleteSelf(s, v, n, equaller).actual()
   414  }
   415  
   416  // DeleteAllSelf deletes value from []interface{} slice in all, by modifying given slice directly.
   417  func DeleteAllSelf(slice []interface{}, value interface{}) []interface{} {
   418  	return coreDeleteSelf(checkInterfaceSliceParam(slice), value, 0, defaultEqualler).actual().([]interface{})
   419  }
   420  
   421  // DeleteAllSelfWith deletes value from []interface{} slice in all with Equaller, by modifying given slice directly.
   422  func DeleteAllSelfWith(slice []interface{}, value interface{}, equaller Equaller) []interface{} {
   423  	return coreDeleteSelf(checkInterfaceSliceParam(slice), value, 0, equaller).actual().([]interface{})
   424  }
   425  
   426  // DeleteAllSelfG deletes value from []T slice in all, by modifying given slice directly, is the generic function of DeleteAll.
   427  func DeleteAllSelfG(slice interface{}, value interface{}) interface{} {
   428  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   429  	return coreDeleteSelf(s, v, 0, defaultEqualler).actual()
   430  }
   431  
   432  // DeleteAllSelfWithG deletes value from []T slice in all with Equaller, by modifying given slice directly, is the generic function of DeleteAllWith.
   433  func DeleteAllSelfWithG(slice interface{}, value interface{}, equaller Equaller) interface{} {
   434  	s, v := checkSliceInterfaceAndElemParam(slice, value)
   435  	return coreDeleteSelf(s, v, 0, equaller).actual()
   436  }
   437  
   438  // coreDeleteSelf is the implementation for DeleteSelf, DeleteSelfWith, DeleteAllSelf, DeleteAllSelfWith, DeleteSelfG, DeleteSelfWithG, DeleteAllSelfG and DeleteAllSelfWithG.
   439  func coreDeleteSelf(slice innerSlice, value interface{}, n int, equaller Equaller) innerSlice {
   440  	if n <= 0 {
   441  		n = slice.length()
   442  	}
   443  	cnt := 0
   444  	idx := coreIndexOf(slice, value, equaller)
   445  	for idx != -1 && cnt < n {
   446  		slice.remove(idx)
   447  		cnt++
   448  		idx = coreIndexOf(slice, value, equaller) // O(n^2)
   449  	}
   450  	return slice
   451  }
   452  
   453  // ContainsAll returns true if values in []interface{} subset are all in the []interface{} list.
   454  func ContainsAll(list, subset []interface{}) bool {
   455  	return coreContainsAll(checkInterfaceSliceParam(list), checkInterfaceSliceParam(subset), defaultEqualler)
   456  }
   457  
   458  // ContainsAllWith returns true if values in []interface{} subset are all in the []interface{} list.
   459  func ContainsAllWith(list, subset []interface{}, equaller Equaller) bool {
   460  	return coreContainsAll(checkInterfaceSliceParam(list), checkInterfaceSliceParam(subset), equaller)
   461  }
   462  
   463  // ContainsAllG returns true if values in []T subset are all in the []T list, is the generic function of ContainsAll.
   464  func ContainsAllG(list, subset interface{}) bool {
   465  	s1, s2 := checkTwoSliceInterfaceParam(list, subset)
   466  	return coreContainsAll(s1, s2, defaultEqualler)
   467  }
   468  
   469  // ContainsAllWithG returns true if values in []T subset are all in the []T list, is the generic function of ContainsAllWith.
   470  func ContainsAllWithG(list, subset interface{}, equaller Equaller) bool {
   471  	s1, s2 := checkTwoSliceInterfaceParam(list, subset)
   472  	return coreContainsAll(s1, s2, equaller)
   473  }
   474  
   475  // coreContainsAll is the implementation for ContainsAll, ContainsAllWith, ContainsAllG and ContainsAllWithG.
   476  func coreContainsAll(list, subset innerSlice, equaller Equaller) bool {
   477  	for i := 0; i < subset.length(); i++ {
   478  		item := subset.get(i)
   479  		if !coreContains(list, item, equaller) {
   480  			return false
   481  		}
   482  	}
   483  	return true
   484  }
   485  
   486  // Diff returns the difference of two []interface{} slices.
   487  func Diff(slice1, slice2 []interface{}) []interface{} {
   488  	return coreDiff(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler).actual().([]interface{})
   489  }
   490  
   491  // DiffWith returns the difference of two []interface{} slices with Equaller.
   492  func DiffWith(slice1, slice2 []interface{}, equaller Equaller) []interface{} {
   493  	return coreDiff(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller).actual().([]interface{})
   494  }
   495  
   496  // DiffG returns the difference of two []T slices, is the generic function of Diff.
   497  func DiffG(slice1, slice2 interface{}) interface{} {
   498  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   499  	return coreDiff(s1, s2, defaultEqualler).actual()
   500  }
   501  
   502  // DiffWithG returns the difference of two []T slices with Equaller, is the generic function of DiffWith.
   503  func DiffWithG(slice1, slice2 interface{}, equaller Equaller) interface{} {
   504  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   505  	return coreDiff(s1, s2, equaller).actual()
   506  }
   507  
   508  // coreDiff is the implementation for Diff, DiffWith, DiffG and DiffWithG.
   509  func coreDiff(slice1, slice2 innerSlice, equaller Equaller) innerSlice {
   510  	result := makeSameTypeInnerSlice(slice1, 0, 0)
   511  	length1 := slice1.length()
   512  	for i1 := 0; i1 < length1; i1++ {
   513  		item1 := slice1.get(i1)
   514  		if !coreContains(slice2, item1, equaller) {
   515  			result.append(item1)
   516  		}
   517  	}
   518  	return result
   519  }
   520  
   521  // Union returns the union of two []interface{} slices.
   522  func Union(slice1, slice2 []interface{}) []interface{} {
   523  	return coreUnion(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler).actual().([]interface{})
   524  }
   525  
   526  // UnionWith returns the union of two []interface{} slices with Equaller.
   527  func UnionWith(slice1, slice2 []interface{}, equaller Equaller) []interface{} {
   528  	return coreUnion(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller).actual().([]interface{})
   529  }
   530  
   531  // UnionG returns the union of two []T slices, is the generic function of Union.
   532  func UnionG(slice1, slice2 interface{}) interface{} {
   533  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   534  	return coreUnion(s1, s2, defaultEqualler).actual()
   535  }
   536  
   537  // UnionWithG returns the union of two []T slices with Equaller, is the generic function of UnionWith.
   538  func UnionWithG(slice1, slice2 interface{}, equaller Equaller) interface{} {
   539  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   540  	return coreUnion(s1, s2, equaller).actual()
   541  }
   542  
   543  // coreUnion is the implementation for Union, UnionWith, UnionG and UnionWithG.
   544  func coreUnion(slice1, slice2 innerSlice, equaller Equaller) innerSlice {
   545  	result := makeSameTypeInnerSlice(slice1, 0, slice1.length())
   546  	length1 := slice1.length()
   547  	for i1 := 0; i1 < length1; i1++ {
   548  		item1 := slice1.get(i1)
   549  		result.append(item1)
   550  	}
   551  	length2 := slice2.length()
   552  	for i2 := 0; i2 < length2; i2++ {
   553  		item2 := slice2.get(i2)
   554  		if !coreContains(slice1, item2, equaller) {
   555  			result.append(item2)
   556  		}
   557  	}
   558  	return result
   559  }
   560  
   561  // Intersect returns the intersection of two []interface{} slices.
   562  func Intersect(slice1, slice2 []interface{}) []interface{} {
   563  	return coreIntersect(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler).actual().([]interface{})
   564  }
   565  
   566  // IntersectWith returns the intersection of two []interface{} slices with Equaller.
   567  func IntersectWith(slice1, slice2 []interface{}, equaller Equaller) []interface{} {
   568  	return coreIntersect(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller).actual().([]interface{})
   569  }
   570  
   571  // IntersectG returns the intersection of two []T slices, is the generic function of Intersect.
   572  func IntersectG(slice1, slice2 interface{}) interface{} {
   573  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   574  	return coreIntersect(s1, s2, defaultEqualler).actual()
   575  }
   576  
   577  // IntersectWithG returns the intersection of two []T slices with Equaller, is the generic function of IntersectWith.
   578  func IntersectWithG(slice1, slice2 interface{}, equaller Equaller) interface{} {
   579  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   580  	return coreIntersect(s1, s2, equaller).actual()
   581  }
   582  
   583  // coreIntersect is the implementation for Intersect, IntersectWith, IntersectG and IntersectWithG.
   584  func coreIntersect(slice1, slice2 innerSlice, equaller Equaller) innerSlice {
   585  	result := makeSameTypeInnerSlice(slice1, 0, 0)
   586  	length1 := slice1.length()
   587  	for i1 := 0; i1 < length1; i1++ {
   588  		item1 := slice1.get(i1)
   589  		if coreContains(slice2, item1, equaller) {
   590  			result.append(item1)
   591  		}
   592  	}
   593  	return result
   594  }
   595  
   596  // Deduplicate removes the duplicate items from []interface{} slice as a set.
   597  func Deduplicate(slice []interface{}) []interface{} {
   598  	return coreDeduplicate(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{})
   599  }
   600  
   601  // DeduplicateWith removes the duplicate items from []interface{} slice as a set with Equaller.
   602  func DeduplicateWith(slice []interface{}, equaller Equaller) []interface{} {
   603  	return coreDeduplicate(checkInterfaceSliceParam(slice), equaller).actual().([]interface{})
   604  }
   605  
   606  // DeduplicateG removes the duplicate items from []T slice as a set, is the generic function of Deduplicate.
   607  func DeduplicateG(slice interface{}) interface{} {
   608  	return coreDeduplicate(checkSliceInterfaceParam(slice), defaultEqualler).actual()
   609  }
   610  
   611  // DeduplicateWithG removes the duplicate items from []T slice as a set with Equaller, is the generic function of DeduplicateWith.
   612  func DeduplicateWithG(slice interface{}, equaller Equaller) interface{} {
   613  	return coreDeduplicate(checkSliceInterfaceParam(slice), equaller).actual()
   614  }
   615  
   616  // coreDeduplicate is the implementation for Deduplicate, DeduplicateWith, DeduplicateG and DeduplicateWithG.
   617  func coreDeduplicate(slice innerSlice, equaller Equaller) innerSlice {
   618  	result := makeSameTypeInnerSlice(slice, 0, 0)
   619  	length := slice.length()
   620  	for idx := 0; idx < length; idx++ {
   621  		item := slice.get(idx)
   622  		if !coreContains(result, item, equaller) { // O(n^2)
   623  			result.append(item)
   624  		}
   625  	}
   626  	return result
   627  }
   628  
   629  // DeduplicateSelf removes the duplicate items from []interface{} slice as a set, by modifying given slice directly.
   630  func DeduplicateSelf(slice []interface{}) []interface{} {
   631  	return coreDeduplicateSelf(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{})
   632  }
   633  
   634  // DeduplicateSelfWith removes the duplicate items from []interface{} slice as a set with Equaller, by modifying given slice directly.
   635  func DeduplicateSelfWith(slice []interface{}, equaller Equaller) []interface{} {
   636  	return coreDeduplicateSelf(checkInterfaceSliceParam(slice), equaller).actual().([]interface{})
   637  }
   638  
   639  // DeduplicateSelfG removes the duplicate items from []T slice as a set, is the generic function of DeduplicateSelf, by modifying given slice directly.
   640  func DeduplicateSelfG(slice interface{}) interface{} {
   641  	return coreDeduplicateSelf(checkSliceInterfaceParam(slice), defaultEqualler).actual()
   642  }
   643  
   644  // DeduplicateSelfWithG removes the duplicate items from []T slice as a set with Equaller, is the generic function of DeduplicateSelfWith, by modifying given slice directly.
   645  func DeduplicateSelfWithG(slice interface{}, equaller Equaller) interface{} {
   646  	return coreDeduplicateSelf(checkSliceInterfaceParam(slice), equaller).actual()
   647  }
   648  
   649  // coreDeduplicate is the implementation for DeduplicateSelf, DeduplicateSelfWith, DeduplicateSelfG and DeduplicateSelfWithG.
   650  func coreDeduplicateSelf(slice innerSlice, equaller Equaller) innerSlice {
   651  	length := slice.length()
   652  	if length <= 1 {
   653  		return slice
   654  	}
   655  	i := 1
   656  	for idx := 1; idx < length; idx++ {
   657  		item := slice.get(idx)
   658  		if !coreContains(slice.slice(0, i), item, equaller) {
   659  			slice.set(i, item)
   660  			i++
   661  		}
   662  	}
   663  	return slice.slice(0, i)
   664  }
   665  
   666  // Compact removes the duplicate items in neighbor from []interface{} slice.
   667  func Compact(slice []interface{}) []interface{} {
   668  	return coreCompact(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{})
   669  }
   670  
   671  // CompactWith removes the duplicate items in neighbor from []interface{} slice with Equaller.
   672  func CompactWith(slice []interface{}, equaller Equaller) []interface{} {
   673  	return coreCompact(checkInterfaceSliceParam(slice), equaller).actual().([]interface{})
   674  }
   675  
   676  // CompactG removes the duplicate items in neighbor from []T slice, is the generic function of Compact.
   677  func CompactG(slice interface{}) interface{} {
   678  	return coreCompact(checkSliceInterfaceParam(slice), defaultEqualler).actual()
   679  }
   680  
   681  // CompactWithG removes the duplicate items in neighbor from []T slice with Equaller, is the generic function of CompactWith.
   682  func CompactWithG(slice interface{}, equaller Equaller) interface{} {
   683  	return coreCompact(checkSliceInterfaceParam(slice), equaller).actual()
   684  }
   685  
   686  // coreCompact is the implementation for Compact, CompactWith, CompactG and CompactWithG.
   687  func coreCompact(slice innerSlice, equaller Equaller) innerSlice {
   688  	length := slice.length()
   689  	if length <= 1 {
   690  		return slice
   691  	}
   692  	result := makeSameTypeInnerSlice(slice, 1, 1)
   693  	last := slice.get(0)
   694  	result.set(0, last)
   695  	for idx := 1; idx < length; idx++ { // O(n)
   696  		item := slice.get(idx)
   697  		if !equaller(item, last) {
   698  			result.append(item)
   699  			last = item
   700  		}
   701  	}
   702  	return result
   703  }
   704  
   705  // CompactSelf removes the duplicate items in neighbor from []interface{} slice, by modifying given slice directly.
   706  func CompactSelf(slice []interface{}) []interface{} {
   707  	return coreCompactSelf(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{})
   708  }
   709  
   710  // CompactSelfWith removes the duplicate items in neighbor from []interface{} slice with Equaller, by modifying given slice directly.
   711  func CompactSelfWith(slice []interface{}, equaller Equaller) []interface{} {
   712  	return coreCompactSelf(checkInterfaceSliceParam(slice), equaller).actual().([]interface{})
   713  }
   714  
   715  // CompactSelfG removes the duplicate items in neighbor from []T slice, is the generic function of CompactSelf, by modifying given slice directly.
   716  func CompactSelfG(slice interface{}) interface{} {
   717  	return coreCompactSelf(checkSliceInterfaceParam(slice), defaultEqualler).actual()
   718  }
   719  
   720  // CompactSelfWithG removes the duplicate items in neighbor from []T slice with Equaller, is the generic function of CompactSelfWith, by modifying given slice directly.
   721  func CompactSelfWithG(slice interface{}, equaller Equaller) interface{} {
   722  	return coreCompactSelf(checkSliceInterfaceParam(slice), equaller).actual()
   723  }
   724  
   725  // coreCompactSelf is the implementation for CompactSelf, CompactSelfWith, CompactSelfG and CompactSelfWithG.
   726  func coreCompactSelf(slice innerSlice, equaller Equaller) innerSlice {
   727  	length := slice.length()
   728  	if length <= 1 {
   729  		return slice
   730  	}
   731  	i := 1
   732  	last := slice.get(0)
   733  	for idx := 1; idx < length; idx++ {
   734  		item := slice.get(idx)
   735  		if !equaller(item, last) {
   736  			slice.set(i, item)
   737  			i++
   738  			last = item
   739  		}
   740  	}
   741  	return slice.slice(0, i)
   742  }
   743  
   744  // Equal checks whether two []interface{} slices equal (the same length and all elements equal).
   745  func Equal(slice1, slice2 []interface{}) bool {
   746  	return coreEqual(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler)
   747  }
   748  
   749  // EqualWith checks whether two []interface{} slices equal (the same length and all elements equal) with Equaller.
   750  func EqualWith(slice1, slice2 []interface{}, equaller Equaller) bool {
   751  	return coreEqual(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller)
   752  }
   753  
   754  // EqualG checks whether two []T slices equal (the same length and all elements equal), is the generic function of Equal.
   755  func EqualG(slice1, slice2 interface{}) bool {
   756  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   757  	return coreEqual(s1, s2, defaultEqualler)
   758  }
   759  
   760  // EqualWithG checks whether two []T slices equal (the same length and all elements equal) with Equaller, is the generic function of EqualWith.
   761  func EqualWithG(slice1, slice2 interface{}, equaller Equaller) bool {
   762  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   763  	return coreEqual(s1, s2, equaller)
   764  }
   765  
   766  // coreEqual is the implementation for Equal, EqualWith, EqualG and EqualWithG.
   767  func coreEqual(slice1, slice2 innerSlice, equaller Equaller) bool {
   768  	length1, length2 := slice1.length(), slice2.length()
   769  	if length1 != length2 {
   770  		return false
   771  	}
   772  	for idx := 0; idx < length1; idx++ {
   773  		item1, item2 := slice1.get(idx), slice2.get(idx)
   774  		if !equaller(item1, item2) {
   775  			return false
   776  		}
   777  	}
   778  	return true
   779  }
   780  
   781  // ElementMatch checks whether two []interface{} slices equal (ignore the order of the elements, but the number of duplicate elements should match).
   782  func ElementMatch(slice1, slice2 []interface{}) bool {
   783  	return coreElementMatch(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler)
   784  }
   785  
   786  // ElementMatchWith checks whether two []interface{} slices equal (ignore the order of the elements, but the number of duplicate elements should match) with Equaller.
   787  func ElementMatchWith(slice1, slice2 []interface{}, equaller Equaller) bool {
   788  	return coreElementMatch(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller)
   789  }
   790  
   791  // ElementMatchG checks whether two []T slices equal (ignore the order of the elements, but the number of duplicate elements should match), is the generic function of ElementMatch.
   792  func ElementMatchG(slice1, slice2 interface{}) bool {
   793  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   794  	return coreElementMatch(s1, s2, defaultEqualler)
   795  }
   796  
   797  // ElementMatchWithG checks whether two []T slices equal (ignore the order of the elements, but the number of duplicate elements should match) with Equaller, is the generic function of ElementMatchWith.
   798  func ElementMatchWithG(slice1, slice2 interface{}, equaller Equaller) bool {
   799  	s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2)
   800  	return coreElementMatch(s1, s2, equaller)
   801  }
   802  
   803  // coreElementMatch is the implementation for ElementMatch, ElementMatchWith, ElementMatchG and ElementMatchWithG.
   804  func coreElementMatch(slice1, slice2 innerSlice, equaller Equaller) bool {
   805  	length1, length2 := slice1.length(), slice2.length()
   806  	visited := make([]bool, length2)
   807  	for idx1 := 0; idx1 < length1; idx1++ {
   808  		item1 := slice1.get(idx1)
   809  		exist := false
   810  		for idx2 := 0; idx2 < length2; idx2++ {
   811  			if visited[idx2] {
   812  				continue
   813  			}
   814  			item2 := slice2.get(idx2)
   815  			if equaller(item1, item2) {
   816  				visited[idx2] = true
   817  				exist = true
   818  				break
   819  			}
   820  		}
   821  		if !exist {
   822  			return false
   823  		}
   824  	}
   825  
   826  	for idx2 := 0; idx2 < length2; idx2++ {
   827  		if !visited[idx2] {
   828  			return false
   829  		}
   830  	}
   831  
   832  	return true
   833  }
   834  
   835  // Repeat generates a []interface{} with given value repeated given count.
   836  func Repeat(value interface{}, count uint) []interface{} {
   837  	return coreRepeat(value, count, false).actual().([]interface{})
   838  }
   839  
   840  // RepeatG generates a []T with given value repeated given count, is the generic function of Repeat.
   841  func RepeatG(value interface{}, count uint) interface{} {
   842  	return coreRepeat(value, count, true).actual().(interface{})
   843  }
   844  
   845  // coreRepeat is the implementation for Repeat and RepeatG.
   846  func coreRepeat(value interface{}, count uint, g bool) innerSlice {
   847  	if value == nil {
   848  		g = false
   849  	}
   850  	slice := makeItemTypeInnerSlice(value, int(count), int(count), g)
   851  	for i := 0; i < int(count); i++ {
   852  		slice.set(i, value)
   853  	}
   854  	return slice
   855  }