github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/utils/generics.go (about)

     1  package utils
     2  
     3  import (
     4  	"golang.org/x/exp/constraints"
     5  	"golang.org/x/exp/slices"
     6  )
     7  
     8  type numbers interface {
     9  	constraints.Integer | constraints.Float | constraints.Complex
    10  }
    11  
    12  // Map like map in Python
    13  func Map[T1, T2 any](slice []T1, f func(T1) T2) []T2 {
    14  	result := make([]T2, len(slice))
    15  	for i, v := range slice {
    16  		result[i] = f(v)
    17  	}
    18  	return result
    19  }
    20  
    21  // Sum returns sum of all elements in slice
    22  func Sum[T numbers](slice []T) T {
    23  	var result T
    24  	for _, v := range slice {
    25  		result += v
    26  	}
    27  	return result
    28  }
    29  
    30  // Min returns the lesser one.
    31  func Min[T constraints.Ordered](x T, xs ...T) T {
    32  	if len(xs) == 0 {
    33  		return x
    34  	}
    35  	if m := Min(xs[0], xs[1:]...); m < x {
    36  		return m
    37  	}
    38  	return x
    39  }
    40  
    41  // Max returns the biggest one.
    42  func Max[T constraints.Ordered](x T, xs ...T) T {
    43  	if len(xs) == 0 {
    44  		return x
    45  	}
    46  	if m := Max(xs[0], xs[1:]...); m > x {
    47  		return m
    48  	}
    49  	return x
    50  }
    51  
    52  // Any returns true if any element in slice meets the requirement
    53  func Any[T any](slice []T, f func(T) bool) bool {
    54  	for _, v := range slice {
    55  		if f(v) {
    56  			return true
    57  		}
    58  	}
    59  	return false
    60  }
    61  
    62  // Filter returns a new slice with elements that meet the requirement
    63  func Filter[T any](slice []T, f func(T) bool) []T {
    64  	if slice == nil {
    65  		return slice
    66  	}
    67  	result := make([]T, 0)
    68  	for _, v := range slice {
    69  		if f(v) {
    70  			result = append(result, v)
    71  		}
    72  	}
    73  	return result
    74  }
    75  
    76  // GenerateSlice generates a slice with factory function
    77  func GenerateSlice[T any](l int, factory func() T) []T {
    78  	result := make([]T, l)
    79  	for i := 0; i < l; i++ {
    80  		result[i] = factory()
    81  	}
    82  	return result
    83  }
    84  
    85  // AdvancedDivide returns 0 when 0/0
    86  func AdvancedDivide[T numbers](a, b T) T {
    87  	if a == 0 || b == 0 {
    88  		return 0
    89  	}
    90  	return a / b
    91  }
    92  
    93  // Reverse any slice
    94  func Reverse[T any](s []T) {
    95  	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
    96  		s[i], s[j] = s[j], s[i]
    97  	}
    98  }
    99  
   100  // Unique return a index, where s[:index] is a unique slice
   101  // Unique requires sorted slice
   102  func Unique[T, E constraints.Ordered](s []T, getVal func(int) E) (j int) {
   103  	slices.Sort(s)
   104  	var lastVal E
   105  	for i := 0; i < len(s); i++ {
   106  		if getVal(i) == lastVal && i != 0 {
   107  			continue
   108  		}
   109  		lastVal = getVal(i)
   110  		s[i], s[j] = s[j], s[i]
   111  		j++
   112  	}
   113  	return j
   114  }