github.com/go-playground/pkg/v5@v5.29.1/slice/slice.go (about) 1 //go:build go1.18 2 // +build go1.18 3 4 package sliceext 5 6 import ( 7 "sort" 8 9 optionext "github.com/go-playground/pkg/v5/values/option" 10 ) 11 12 // Retain retains only the elements specified by the function. 13 // 14 // This returns a new slice with references to the underlying data instead of shuffling. 15 func Retain[T any](slice []T, fn func(v T) bool) []T { 16 results := make([]T, 0, len(slice)) 17 for _, v := range slice { 18 v := v 19 if fn(v) { 20 results = append(results, v) 21 } 22 } 23 return results 24 } 25 26 // Filter filters out the elements specified by the function. 27 // 28 // This returns a new slice with references to the underlying data instead of shuffling. 29 func Filter[T any](slice []T, fn func(v T) bool) []T { 30 results := make([]T, 0, len(slice)) 31 for _, v := range slice { 32 v := v 33 if fn(v) { 34 continue 35 } 36 results = append(results, v) 37 } 38 return results 39 } 40 41 // Map maps a slice of []T -> []U using the map function. 42 func Map[T, U any](slice []T, init U, fn func(accum U, v T) U) U { 43 if len(slice) == 0 { 44 return init 45 } 46 accum := init 47 for _, v := range slice { 48 accum = fn(accum, v) 49 } 50 return accum 51 } 52 53 // Sort sorts the sliceWrapper x given the provided less function. 54 // 55 // The sort is not guaranteed to be stable: equal elements 56 // may be reversed from their original order. 57 // 58 // For a stable sort, use SortStable. 59 func Sort[T any](slice []T, less func(i T, j T) bool) { 60 sort.Slice(slice, func(j, k int) bool { 61 return less(slice[j], slice[k]) 62 }) 63 } 64 65 // SortStable sorts the sliceWrapper x using the provided less 66 // function, keeping equal elements in their original order. 67 func SortStable[T any](slice []T, less func(i T, j T) bool) { 68 sort.SliceStable(slice, func(j, k int) bool { 69 return less(slice[j], slice[k]) 70 }) 71 } 72 73 // Reduce reduces the elements to a single one, by repeatedly applying a reducing function. 74 func Reduce[T any](slice []T, fn func(accum T, current T) T) optionext.Option[T] { 75 if len(slice) == 0 { 76 return optionext.None[T]() 77 } 78 accum := slice[0] 79 for _, v := range slice { 80 accum = fn(accum, v) 81 } 82 return optionext.Some(accum) 83 } 84 85 // Reverse reverses the slice contents. 86 func Reverse[T any](slice []T) { 87 for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 { 88 slice[i], slice[j] = slice[j], slice[i] 89 } 90 }