github.com/andeya/ameda@v1.5.3/int8s.go (about)

     1  package ameda
     2  
     3  // OneInt8 try to return the first element, otherwise return zero value.
     4  func OneInt8(i []int8) int8 {
     5  	if len(i) > 0 {
     6  		return i[0]
     7  	}
     8  	return 0
     9  }
    10  
    11  // Int8sCopy creates a copy of the int8 slice.
    12  func Int8sCopy(i []int8) []int8 {
    13  	b := make([]int8, len(i))
    14  	copy(b, i)
    15  	return b
    16  }
    17  
    18  // Int8sToInterfaces converts int8 slice to interface slice.
    19  func Int8sToInterfaces(i []int8) []interface{} {
    20  	r := make([]interface{}, len(i))
    21  	for k, v := range i {
    22  		r[k] = v
    23  	}
    24  	return r
    25  }
    26  
    27  // Int8sToStrings converts int8 slice to string slice.
    28  func Int8sToStrings(i []int8) []string {
    29  	r := make([]string, len(i))
    30  	for k, v := range i {
    31  		r[k] = Int8ToString(v)
    32  	}
    33  	return r
    34  }
    35  
    36  // Int8sToBools converts int8 slice to bool slice.
    37  // NOTE:
    38  //
    39  //	0 is false, everything else is true
    40  func Int8sToBools(i []int8) []bool {
    41  	r := make([]bool, len(i))
    42  	for k, v := range i {
    43  		r[k] = Int8ToBool(v)
    44  	}
    45  	return r
    46  }
    47  
    48  // Int8sToFloat32s converts int8 slice to float32 slice.
    49  func Int8sToFloat32s(i []int8) []float32 {
    50  	r := make([]float32, len(i))
    51  	for k, v := range i {
    52  		r[k] = Int8ToFloat32(v)
    53  	}
    54  	return r
    55  }
    56  
    57  // Int8sToFloat64s converts int8 slice to float64 slice.
    58  func Int8sToFloat64s(i []int8) []float64 {
    59  	r := make([]float64, len(i))
    60  	for k, v := range i {
    61  		r[k] = Int8ToFloat64(v)
    62  	}
    63  	return r
    64  }
    65  
    66  // Int8sToInts converts int8 slice to int slice.
    67  func Int8sToInts(i []int8) []int {
    68  	r := make([]int, len(i))
    69  	for k, v := range i {
    70  		r[k] = Int8ToInt(v)
    71  	}
    72  	return r
    73  }
    74  
    75  // Ints converts int8 slice to int slice.
    76  func Int8sInts(i []int8) []int {
    77  	return Int8sToInts(i)
    78  }
    79  
    80  // Int8sToInt16s converts int8 slice to int16 slice.
    81  func Int8sToInt16s(i []int8) []int16 {
    82  	r := make([]int16, len(i))
    83  	for k, v := range i {
    84  		r[k] = Int8ToInt16(v)
    85  	}
    86  	return r
    87  }
    88  
    89  // Int8sToInt32s converts int8 slice to int32 slice.
    90  func Int8sToInt32s(i []int8) []int32 {
    91  	r := make([]int32, len(i))
    92  	for k, v := range i {
    93  		r[k] = Int8ToInt32(v)
    94  	}
    95  	return r
    96  }
    97  
    98  // Int8sToInt64s converts int8 slice to int64 slice.
    99  func Int8sToInt64s(i []int8) []int64 {
   100  	r := make([]int64, len(i))
   101  	for k, v := range i {
   102  		r[k] = Int8ToInt64(v)
   103  	}
   104  	return r
   105  }
   106  
   107  // Int8sToUints converts int8 slice to uint slice.
   108  func Int8sToUints(i []int8) ([]uint, error) {
   109  	var err error
   110  	r := make([]uint, len(i))
   111  	for k, v := range i {
   112  		r[k], err = Int8ToUint(v)
   113  		if err != nil {
   114  			return r, err
   115  		}
   116  	}
   117  	return r, nil
   118  }
   119  
   120  // Int8sToUint8s converts int8 slice to uint8 slice.
   121  func Int8sToUint8s(i []int8) ([]uint8, error) {
   122  	var err error
   123  	r := make([]uint8, len(i))
   124  	for k, v := range i {
   125  		r[k], err = Int8ToUint8(v)
   126  		if err != nil {
   127  			return r, err
   128  		}
   129  	}
   130  	return r, nil
   131  }
   132  
   133  // Int8sToUint16s converts int8 slice to uint16 slice.
   134  func Int8sToUint16s(i []int8) ([]uint16, error) {
   135  	var err error
   136  	r := make([]uint16, len(i))
   137  	for k, v := range i {
   138  		r[k], err = Int8ToUint16(v)
   139  		if err != nil {
   140  			return r, err
   141  		}
   142  	}
   143  	return r, nil
   144  }
   145  
   146  // Int8sToUint32s converts int8 slice to uint32 slice.
   147  func Int8sToUint32s(i []int8) ([]uint32, error) {
   148  	var err error
   149  	r := make([]uint32, len(i))
   150  	for k, v := range i {
   151  		r[k], err = Int8ToUint32(v)
   152  		if err != nil {
   153  			return r, err
   154  		}
   155  	}
   156  	return r, nil
   157  }
   158  
   159  // Int8sToUint64s converts int8 slice to uint64 slice.
   160  func Int8sToUint64s(i []int8) ([]uint64, error) {
   161  	var err error
   162  	r := make([]uint64, len(i))
   163  	for k, v := range i {
   164  		r[k], err = Int8ToUint64(v)
   165  		if err != nil {
   166  			return r, err
   167  		}
   168  	}
   169  	return r, nil
   170  }
   171  
   172  // Int8sCopyWithin copies part of an slice to another location in the current slice.
   173  // @target
   174  //
   175  //	Zero-based index at which to copy the sequence to. If negative, target will be counted from the end.
   176  //
   177  // @start
   178  //
   179  //	Zero-based index at which to start copying elements from. If negative, start will be counted from the end.
   180  //
   181  // @end
   182  //
   183  //	Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end.
   184  //	If negative, end will be counted from the end.
   185  //	If end is omitted, CopyWithin will copy until the last index (default to len(s)).
   186  func Int8sCopyWithin(i []int8, target, start int, end ...int) {
   187  	target = fixIndex(len(i), target, true)
   188  	if target == len(i) {
   189  		return
   190  	}
   191  	sub := Int8sSlice(i, start, end...)
   192  	for k, v := range sub {
   193  		i[target+k] = v
   194  	}
   195  }
   196  
   197  // Int8sEvery tests whether all elements in the slice pass the test implemented by the provided function.
   198  // NOTE:
   199  //
   200  //	Calling this method on an empty slice will return true for any condition!
   201  func Int8sEvery(i []int8, fn func(i []int8, k int, v int8) bool) bool {
   202  	for k, v := range i {
   203  		if !fn(i, k, v) {
   204  			return false
   205  		}
   206  	}
   207  	return true
   208  }
   209  
   210  // Int8sFill changes all elements in the current slice to a value, from a start index to an end index.
   211  // @value
   212  //
   213  //	Zero-based index at which to copy the sequence to. If negative, target will be counted from the end.
   214  //
   215  // @start
   216  //
   217  //	Zero-based index at which to start copying elements from. If negative, start will be counted from the end.
   218  //
   219  // @end
   220  //
   221  //	Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end.
   222  //	If negative, end will be counted from the end.
   223  //	If end is omitted, CopyWithin will copy until the last index (default to len(s)).
   224  func Int8sFill(i []int8, value int8, start int, end ...int) {
   225  	fixedStart, fixedEnd, ok := fixRange(len(i), start, end...)
   226  	if !ok {
   227  		return
   228  	}
   229  	for k := fixedStart; k < fixedEnd; k++ {
   230  		i[k] = value
   231  	}
   232  }
   233  
   234  // Int8sFilter creates a new slice with all elements that pass the test implemented by the provided function.
   235  func Int8sFilter(i []int8, fn func(i []int8, k int, v int8) bool) []int8 {
   236  	ret := make([]int8, 0)
   237  	for k, v := range i {
   238  		if fn(i, k, v) {
   239  			ret = append(ret, v)
   240  		}
   241  	}
   242  	return ret
   243  }
   244  
   245  // Int8sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function.
   246  // NOTE:
   247  //
   248  //	If not found, k = -1
   249  func Int8sFind(i []int8, fn func(i []int8, k int, v int8) bool) (k int, v int8) {
   250  	for k, v := range i {
   251  		if fn(i, k, v) {
   252  			return k, v
   253  		}
   254  	}
   255  	return -1, 0
   256  }
   257  
   258  // Int8sIncludes determines whether an slice includes a certain value among its entries.
   259  // @fromIndex
   260  //
   261  //	The index to start the search at. Defaults to 0.
   262  func Int8sIncludes(i []int8, valueToFind int8, fromIndex ...int) bool {
   263  	return Int8sIndexOf(i, valueToFind, fromIndex...) > -1
   264  }
   265  
   266  // Int8sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present.
   267  // @fromIndex
   268  //
   269  //	The index to start the search at. Defaults to 0.
   270  func Int8sIndexOf(i []int8, searchElement int8, fromIndex ...int) int {
   271  	idx := getFromIndex(len(i), fromIndex...)
   272  	for k, v := range i[idx:] {
   273  		if searchElement == v {
   274  			return k + idx
   275  		}
   276  	}
   277  	return -1
   278  }
   279  
   280  // Int8sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present.
   281  // @fromIndex
   282  //
   283  //	The index to start the search at. Defaults to 0.
   284  func Int8sLastIndexOf(i []int8, searchElement int8, fromIndex ...int) int {
   285  	idx := getFromIndex(len(i), fromIndex...)
   286  	for k := len(i) - 1; k >= idx; k-- {
   287  		if searchElement == i[k] {
   288  			return k
   289  		}
   290  	}
   291  	return -1
   292  }
   293  
   294  // Int8sMap creates a new slice populated with the results of calling a provided function
   295  // on every element in the calling slice.
   296  func Int8sMap(i []int8, fn func(i []int8, k int, v int8) int8) []int8 {
   297  	ret := make([]int8, len(i))
   298  	for k, v := range i {
   299  		ret[k] = fn(i, k, v)
   300  	}
   301  	return ret
   302  }
   303  
   304  // Int8sPop removes the last element from an slice and returns that element.
   305  // This method changes the length of the slice.
   306  func Int8sPop(i *[]int8) (int8, bool) {
   307  	a := *i
   308  	if len(a) == 0 {
   309  		return 0, false
   310  	}
   311  	lastIndex := len(a) - 1
   312  	last := a[lastIndex]
   313  	a = a[:lastIndex]
   314  	*i = a[:len(a):len(a)]
   315  	return last, true
   316  }
   317  
   318  // Int8sPush adds one or more elements to the end of an slice and returns the new length of the slice.
   319  func Int8sPush(i *[]int8, element ...int8) int {
   320  	*i = append(*i, element...)
   321  	return len(*i)
   322  }
   323  
   324  // Int8sPushDistinct adds one or more new elements that do not exist in the current slice at the end.
   325  func Int8sPushDistinct(i []int8, element ...int8) []int8 {
   326  L:
   327  	for _, v := range element {
   328  		for _, vv := range i {
   329  			if vv == v {
   330  				continue L
   331  			}
   332  		}
   333  		i = append(i, v)
   334  	}
   335  	return i
   336  }
   337  
   338  // Int8sReduce executes a reducer function (that you provide) on each element of the slice,
   339  // resulting in a single output value.
   340  // @accumulator
   341  //
   342  //	The accumulator accumulates callback's return values.
   343  //	It is the accumulated value previously returned in the last invocation of the callback—or initialValue,
   344  //	if it was supplied (see below).
   345  //
   346  // @initialValue
   347  //
   348  //	A value to use as the first argument to the first call of the callback.
   349  //	If no initialValue is supplied, the first element in the slice will be used and skipped.
   350  func Int8sReduce(i []int8,
   351  	fn func(i []int8, k int, v, accumulator int8) int8, initialValue ...int8,
   352  ) int8 {
   353  	if len(i) == 0 {
   354  		return 0
   355  	}
   356  	start := 0
   357  	acc := i[start]
   358  	if len(initialValue) > 0 {
   359  		acc = initialValue[0]
   360  	} else {
   361  		start += 1
   362  	}
   363  	for k := start; k < len(i); k++ {
   364  		acc = fn(i, k, i[k], acc)
   365  	}
   366  	return acc
   367  }
   368  
   369  // Int8sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left)
   370  // to reduce it to a single value.
   371  // @accumulator
   372  //
   373  //	The accumulator accumulates callback's return values.
   374  //	It is the accumulated value previously returned in the last invocation of the callback—or initialValue,
   375  //	if it was supplied (see below).
   376  //
   377  // @initialValue
   378  //
   379  //	A value to use as the first argument to the first call of the callback.
   380  //	If no initialValue is supplied, the first element in the slice will be used and skipped.
   381  func Int8sReduceRight(i []int8,
   382  	fn func(i []int8, k int, v, accumulator int8) int8, initialValue ...int8,
   383  ) int8 {
   384  	if len(i) == 0 {
   385  		return 0
   386  	}
   387  	end := len(i) - 1
   388  	acc := i[end]
   389  	if len(initialValue) > 0 {
   390  		acc = initialValue[0]
   391  	} else {
   392  		end -= 1
   393  	}
   394  	for k := end; k >= 0; k-- {
   395  		acc = fn(i, k, i[k], acc)
   396  	}
   397  	return acc
   398  }
   399  
   400  // Int8sReverse reverses an slice in place.
   401  func Int8sReverse(i []int8) {
   402  	first := 0
   403  	last := len(i) - 1
   404  	for first < last {
   405  		i[first], i[last] = i[last], i[first]
   406  		first++
   407  		last--
   408  	}
   409  }
   410  
   411  // Int8sShift removes the first element from an slice and returns that removed element.
   412  // This method changes the length of the slice.
   413  func Int8sShift(i *[]int8) (int8, bool) {
   414  	a := *i
   415  	if len(a) == 0 {
   416  		return 0, false
   417  	}
   418  	first := a[0]
   419  	a = a[1:]
   420  	*i = a[:len(a):len(a)]
   421  	return first, true
   422  }
   423  
   424  // Int8sSlice returns a copy of a portion of an slice into a new slice object selected
   425  // from begin to end (end not included) where begin and end represent the index of items in that slice.
   426  // The original slice will not be modified.
   427  func Int8sSlice(i []int8, begin int, end ...int) []int8 {
   428  	fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...)
   429  	if !ok {
   430  		return []int8{}
   431  	}
   432  	return Int8sCopy(i[fixedStart:fixedEnd])
   433  }
   434  
   435  // Int8sSome tests whether at least one element in the slice passes the test implemented by the provided function.
   436  // NOTE:
   437  //
   438  //	Calling this method on an empty slice returns false for any condition!
   439  func Int8sSome(i []int8, fn func(i []int8, k int, v int8) bool) bool {
   440  	for k, v := range i {
   441  		if fn(i, k, v) {
   442  			return true
   443  		}
   444  	}
   445  	return false
   446  }
   447  
   448  // Int8sSplice changes the contents of an slice by removing or replacing
   449  // existing elements and/or adding new elements in place.
   450  func Int8sSplice(i *[]int8, start, deleteCount int, items ...int8) {
   451  	a := *i
   452  	if deleteCount < 0 {
   453  		deleteCount = 0
   454  	}
   455  	start, end, _ := fixRange(len(a), start, start+1+deleteCount)
   456  	deleteCount = end - start - 1
   457  	for k := 0; k < len(items); k++ {
   458  		if deleteCount > 0 {
   459  			// replace
   460  			a[start] = items[k]
   461  			deleteCount--
   462  			start++
   463  		} else {
   464  			// insert
   465  			lastSlice := Int8sCopy(a[start:])
   466  			items = items[k:]
   467  			a = append(a[:start], items...)
   468  			a = append(a[:start+len(items)], lastSlice...)
   469  			*i = a[:len(a):len(a)]
   470  			return
   471  		}
   472  	}
   473  	if deleteCount > 0 {
   474  		a = append(a[:start], a[start+1+deleteCount:]...)
   475  	}
   476  	*i = a[:len(a):len(a)]
   477  }
   478  
   479  // Int8sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice.
   480  func Int8sUnshift(i *[]int8, element ...int8) int {
   481  	*i = append(element, *i...)
   482  	return len(*i)
   483  }
   484  
   485  // Int8sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning
   486  // and returns the new length of the slice.
   487  func Int8sUnshiftDistinct(i *[]int8, element ...int8) int {
   488  	a := *i
   489  	if len(element) == 0 {
   490  		return len(a)
   491  	}
   492  	m := make(map[int8]bool, len(element))
   493  	r := make([]int8, 0, len(a)+len(element))
   494  L:
   495  	for _, v := range element {
   496  		if m[v] {
   497  			continue
   498  		}
   499  		m[v] = true
   500  		for _, vv := range a {
   501  			if vv == v {
   502  				continue L
   503  			}
   504  		}
   505  		r = append(r, v)
   506  	}
   507  	r = append(r, a...)
   508  	*i = r[:len(r):len(r)]
   509  	return len(r)
   510  }
   511  
   512  // Int8sRemoveFirst removes the first matched elements from the slice,
   513  // and returns the new length of the slice.
   514  func Int8sRemoveFirst(p *[]int8, elements ...int8) int {
   515  	a := *p
   516  	m := make(map[interface{}]struct{}, len(elements))
   517  	for _, element := range elements {
   518  		if _, ok := m[element]; ok {
   519  			continue
   520  		}
   521  		m[element] = struct{}{}
   522  		for k, v := range a {
   523  			if v == element {
   524  				a = append(a[:k], a[k+1:]...)
   525  				break
   526  			}
   527  		}
   528  	}
   529  	n := len(a)
   530  	*p = a[:n:n]
   531  	return n
   532  }
   533  
   534  // Int8sRemoveEvery removes all the elements from the slice,
   535  // and returns the new length of the slice.
   536  func Int8sRemoveEvery(p *[]int8, elements ...int8) int {
   537  	a := *p
   538  	m := make(map[interface{}]struct{}, len(elements))
   539  	for _, element := range elements {
   540  		if _, ok := m[element]; ok {
   541  			continue
   542  		}
   543  		m[element] = struct{}{}
   544  		for i := 0; i < len(a); i++ {
   545  			if a[i] == element {
   546  				a = append(a[:i], a[i+1:]...)
   547  				i--
   548  			}
   549  		}
   550  	}
   551  	n := len(a)
   552  	*p = a[:n:n]
   553  	return n
   554  }
   555  
   556  // Int8sConcat is used to merge two or more slices.
   557  // This method does not change the existing slices, but instead returns a new slice.
   558  func Int8sConcat(i ...[]int8) []int8 {
   559  	var totalLen int
   560  	for _, v := range i {
   561  		totalLen += len(v)
   562  	}
   563  	ret := make([]int8, totalLen)
   564  	dst := ret
   565  	for _, v := range i {
   566  		n := copy(dst, v)
   567  		dst = dst[n:]
   568  	}
   569  	return ret
   570  }
   571  
   572  // Int8sIntersect calculates intersection of two or more slices,
   573  // and returns the count of each element.
   574  func Int8sIntersect(i ...[]int8) (intersectCount map[int8]int) {
   575  	if len(i) == 0 {
   576  		return nil
   577  	}
   578  	for _, v := range i {
   579  		if len(v) == 0 {
   580  			return nil
   581  		}
   582  	}
   583  	counts := make([]map[int8]int, len(i))
   584  	for k, v := range i {
   585  		counts[k] = int8sDistinct(v, nil)
   586  	}
   587  	intersectCount = counts[0]
   588  L:
   589  	for k, v := range intersectCount {
   590  		for _, c := range counts[1:] {
   591  			v2 := c[k]
   592  			if v2 == 0 {
   593  				delete(intersectCount, k)
   594  				continue L
   595  			}
   596  			if v > v2 {
   597  				v = v2
   598  			}
   599  		}
   600  		intersectCount[k] = v
   601  	}
   602  	return intersectCount
   603  }
   604  
   605  // Int8sDistinct calculates the count of each different element,
   606  // and only saves these different elements in place if changeSlice is true.
   607  func Int8sDistinct(i *[]int8, changeSlice bool) (distinctCount map[int8]int) {
   608  	if !changeSlice {
   609  		return int8sDistinct(*i, nil)
   610  	}
   611  	a := (*i)[:0]
   612  	distinctCount = int8sDistinct(*i, &a)
   613  	n := len(distinctCount)
   614  	*i = a[:n:n]
   615  	return distinctCount
   616  }
   617  
   618  func int8sDistinct(src []int8, dst *[]int8) map[int8]int {
   619  	m := make(map[int8]int, len(src))
   620  	if dst == nil {
   621  		for _, v := range src {
   622  			n := m[v]
   623  			m[v] = n + 1
   624  		}
   625  	} else {
   626  		a := *dst
   627  		for _, v := range src {
   628  			n := m[v]
   629  			m[v] = n + 1
   630  			if n == 0 {
   631  				a = append(a, v)
   632  			}
   633  		}
   634  		*dst = a
   635  	}
   636  	return m
   637  }
   638  
   639  // Int8SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others...
   640  // This method does not change the existing slices, but instead returns a new slice.
   641  func Int8SetUnion(set1, set2 []int8, others ...[]int8) []int8 {
   642  	m := make(map[int8]struct{}, len(set1)+len(set2))
   643  	r := make([]int8, 0, len(m))
   644  	for _, set := range append([][]int8{set1, set2}, others...) {
   645  		for _, v := range set {
   646  			_, ok := m[v]
   647  			if ok {
   648  				continue
   649  			}
   650  			r = append(r, v)
   651  			m[v] = struct{}{}
   652  		}
   653  	}
   654  	return r
   655  }
   656  
   657  // Int8SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others...
   658  // This method does not change the existing slices, but instead returns a new slice.
   659  func Int8SetIntersect(set1, set2 []int8, others ...[]int8) []int8 {
   660  	sets := append([][]int8{set2}, others...)
   661  	setsCount := make([]map[int8]int, len(sets))
   662  	for k, v := range sets {
   663  		setsCount[k] = int8sDistinct(v, nil)
   664  	}
   665  	m := make(map[int8]struct{}, len(set1))
   666  	r := make([]int8, 0, len(m))
   667  L:
   668  	for _, v := range set1 {
   669  		if _, ok := m[v]; ok {
   670  			continue
   671  		}
   672  		m[v] = struct{}{}
   673  		for _, m2 := range setsCount {
   674  			if m2[v] == 0 {
   675  				continue L
   676  			}
   677  		}
   678  		r = append(r, v)
   679  	}
   680  	return r
   681  }
   682  
   683  // Int8SetDifference calculates between multiple collections: set1 - set2 - others...
   684  // This method does not change the existing slices, but instead returns a new slice.
   685  func Int8SetDifference(set1, set2 []int8, others ...[]int8) []int8 {
   686  	m := make(map[int8]struct{}, len(set1))
   687  	r := make([]int8, 0, len(set1))
   688  	sets := append([][]int8{set2}, others...)
   689  	for _, v := range sets {
   690  		inter := Int8SetIntersect(set1, v)
   691  		for _, v := range inter {
   692  			m[v] = struct{}{}
   693  		}
   694  	}
   695  	for _, v := range set1 {
   696  		if _, ok := m[v]; !ok {
   697  			r = append(r, v)
   698  			m[v] = struct{}{}
   699  		}
   700  	}
   701  	return r
   702  }