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

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