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

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