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

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