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

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