slice.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package generics
  2. import (
  3. "golang.org/x/exp/constraints"
  4. )
  5. // Pops the last element from the slice and returns it. Panics if the slice is empty, or if the
  6. // slice is nil.
  7. func SlicePop[T any](slice *[]T) T {
  8. lastIndex := len(*slice) - 1
  9. last := (*slice)[lastIndex]
  10. *slice = (*slice)[:lastIndex]
  11. return last
  12. }
  13. func MakeSliceWithLength[T any, L constraints.Integer](slice *[]T, length L) {
  14. *slice = make([]T, length)
  15. }
  16. func MakeSliceWithCap[T any, L constraints.Integer](slice *[]T, cap L) {
  17. *slice = make([]T, 0, cap)
  18. }
  19. func Reversed[T any](slice []T) []T {
  20. reversed := make([]T, len(slice))
  21. for i := range reversed {
  22. reversed[i] = slice[len(slice)-1-i]
  23. }
  24. return reversed
  25. }
  26. func Singleton[T any](t T) []T {
  27. return []T{t}
  28. }
  29. // I take it there's no way to do this with a generic return slice element type.
  30. func ConvertToSliceOfAny[T any](ts []T) (ret []any) {
  31. ret = make([]any, 0, len(ts))
  32. for _, t := range ts {
  33. ret = append(ret, t)
  34. }
  35. return
  36. }
  37. func ReverseSlice[T any](slice []T) {
  38. for i := 0; i < len(slice)/2; i++ {
  39. slice[i], slice[len(slice)-1-i] = slice[len(slice)-1-i], slice[i]
  40. }
  41. }
  42. func SliceTake[T any](n int, slice []T) []T {
  43. return slice[:Min(n, len(slice))]
  44. }
  45. func SliceDrop[T any](n int, slice []T) []T {
  46. return slice[Min(n, len(slice)):]
  47. }
  48. func SliceGet[T any, I constraints.Integer](slice []T, index I) (ret Option[T]) {
  49. if int(index) < len(slice) {
  50. ret = Some(slice[index])
  51. }
  52. return
  53. }
  54. // Surely you should just pass iterator functions around instead. Go sux.
  55. func SliceMap[From, To any](froms []From, convert func(From) To) []To {
  56. tos := make([]To, 0, len(froms))
  57. for _, from := range froms {
  58. tos = append(tos, convert(from))
  59. }
  60. return tos
  61. }