From 6498c7d68ab1d01a50566099341ad5d795451034 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Thu, 5 Jan 2023 11:26:56 +0800 Subject: [PATCH] test: add examples for slice package --- slice/slice.go | 57 ++++++--- slice/slice_example_test.go | 230 ++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+), 18 deletions(-) diff --git a/slice/slice.go b/slice/slice.go index 59d5e0a..24eaab9 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -10,6 +10,7 @@ import ( "math/rand" "reflect" "sort" + "time" "golang.org/x/exp/constraints" ) @@ -614,6 +615,7 @@ func UpdateAt[T any](slice []T, index int, value T) []T { } // Unique remove duplicate elements in slice. +// Play: https://go.dev/play/p/AXw0R3ZTE6a func Unique[T comparable](slice []T) []T { result := []T{} @@ -635,6 +637,7 @@ func Unique[T comparable](slice []T) []T { } // UniqueBy call iteratee func with every item of slice, then remove duplicated. +// Play: https://go.dev/play/p/UR323iZLDpv func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T { result := []T{} @@ -647,6 +650,7 @@ func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T { } // Union creates a slice of unique elements, in order, from all given slices. +// Play: https://go.dev/play/p/hfXV1iRIZOf func Union[T comparable](slices ...[]T) []T { result := []T{} contain := map[T]struct{}{} @@ -663,7 +667,8 @@ func Union[T comparable](slices ...[]T) []T { return result } -// UnionBy is like Union, what's more it accepts iteratee which is invoked for each element of each slice +// UnionBy is like Union, what's more it accepts iteratee which is invoked for each element of each slice. +// Play: https://go.dev/play/p/HGKHfxKQsFi func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T { result := []T{} contain := map[V]struct{}{} @@ -681,7 +686,8 @@ func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T { return result } -// Merge all given slices into one slice +// Merge all given slices into one slice. +// Play: https://go.dev/play/p/lbjFp784r9N func Merge[T any](slices ...[]T) []T { result := make([]T, 0) @@ -693,6 +699,7 @@ func Merge[T any](slices ...[]T) []T { } // Intersection creates a slice of unique elements that included by all slices. +// Play: https://go.dev/play/p/anJXfB5wq_t func Intersection[T comparable](slices ...[]T) []T { if len(slices) == 0 { return []T{} @@ -729,7 +736,8 @@ func Intersection[T comparable](slices ...[]T) []T { return result } -// SymmetricDifference oppoiste operation of intersection function +// SymmetricDifference oppoiste operation of intersection function. +// Play: https://go.dev/play/p/h42nJX5xMln func SymmetricDifference[T comparable](slices ...[]T) []T { if len(slices) == 0 { return []T{} @@ -755,25 +763,29 @@ func SymmetricDifference[T comparable](slices ...[]T) []T { return Unique(result) } -// Reverse return slice of element order is reversed to the given slice +// Reverse return slice of element order is reversed to the given slice. +// Play: https://go.dev/play/p/8uI8f1lwNrQ func Reverse[T any](slice []T) { for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 { slice[i], slice[j] = slice[j], slice[i] } } -// Shuffle creates an slice of shuffled values +// Shuffle creates an slice of shuffled values. +// Play: https://go.dev/play/p/YHvhnWGU3Ge func Shuffle[T any](slice []T) []T { - result := make([]T, len(slice)) - for i, v := range rand.Perm(len(slice)) { - result[i] = slice[v] - } + rand.Seed(time.Now().UnixNano()) - return result + rand.Shuffle(len(slice), func(i, j int) { + slice[i], slice[j] = slice[j], slice[i] + }) + + return slice } // Sort sorts a slice of any ordered type(number or string), use quick sort algrithm. -// default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc` +// default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`. +// Play: https://go.dev/play/p/V9AVjzf_4Fk func Sort[T constraints.Ordered](slice []T, sortOrder ...string) { if len(sortOrder) > 0 && sortOrder[0] == "desc" { quickSort(slice, 0, len(slice)-1, "desc") @@ -783,7 +795,8 @@ func Sort[T constraints.Ordered](slice []T, sortOrder ...string) { } // SortBy sorts the slice in ascending order as determined by the less function. -// This sort is not guaranteed to be stable +// This sort is not guaranteed to be stable. +// Play: https://go.dev/play/p/DAhLQSZEumm func SortBy[T any](slice []T, less func(a, b T) bool) { quickSortBy(slice, 0, len(slice)-1, less) } @@ -791,7 +804,8 @@ func SortBy[T any](slice []T, less func(a, b T) bool) { // SortByField return sorted slice by field // slice element should be struct, field type should be int, uint, string, or bool // default sortType is ascending (asc), if descending order, set sortType to desc -// This function is deprecated, use Sort and SortBy for replacement +// This function is deprecated, use Sort and SortBy for replacement. +// Play: https://go.dev/play/p/fU1prOBP9p1 func SortByField(slice any, field string, sortType ...string) error { sv := sliceValue(slice) t := sv.Type().Elem() @@ -861,7 +875,8 @@ func SortByField(slice any, field string, sortType ...string) error { return nil } -// Without creates a slice excluding all given items +// Without creates a slice excluding all given items. +// Play: https://go.dev/play/p/bwhEXEypThg func Without[T comparable](slice []T, items ...T) []T { if len(items) == 0 || len(slice) == 0 { return slice @@ -878,6 +893,7 @@ func Without[T comparable](slice []T, items ...T) []T { } // IndexOf returns the index at which the first occurrence of an item is found in a slice or return -1 if the item cannot be found. +// Play: https://go.dev/play/p/MRN1f0FpABb func IndexOf[T comparable](arr []T, val T) int { limit := 10 // gets the hash value of the array as the key of the hash table. @@ -919,6 +935,7 @@ func IndexOf[T comparable](arr []T, val T) int { } // LastIndexOf returns the index at which the last occurrence of the item is found in a slice or return -1 if the then cannot be found. +// Play: https://go.dev/play/p/DokM4cf1IKH func LastIndexOf[T comparable](slice []T, item T) int { for i := len(slice) - 1; i > 0; i-- { if item == slice[i] { @@ -929,7 +946,8 @@ func LastIndexOf[T comparable](slice []T, item T) int { return -1 } -// ToSlicePointer returns a pointer to the slices of a variable parameter transformation +// ToSlicePointer returns a pointer to the slices of a variable parameter transformation. +// Play: https://go.dev/play/p/gx4tr6_VXSF func ToSlicePointer[T any](items ...T) []*T { result := make([]*T, len(items)) for i := range items { @@ -939,7 +957,8 @@ func ToSlicePointer[T any](items ...T) []*T { return result } -// ToSlice returns a slices of a variable parameter transformation +// ToSlice returns a slices of a variable parameter transformation. +// Play: https://go.dev/play/p/YzbzVq5kscN func ToSlice[T any](items ...T) []T { result := make([]T, len(items)) copy(result, items) @@ -947,7 +966,8 @@ func ToSlice[T any](items ...T) []T { return result } -// AppendIfAbsent only absent append the item +// AppendIfAbsent only absent append the item. +// Play: https://go.dev/play/p/KcC1QXQ-RkL func AppendIfAbsent[T comparable](slice []T, item T) []T { if !Contain(slice, item) { slice = append(slice, item) @@ -955,7 +975,8 @@ func AppendIfAbsent[T comparable](slice []T, item T) []T { return slice } -// KeyBy converts a slice to a map based on a callback function +// KeyBy converts a slice to a map based on a callback function. +// Play: https://go.dev/play/p/uXod2LWD1Kg func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T { result := make(map[U]T, len(slice)) diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index f61bb8d..d22412c 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -3,6 +3,7 @@ package slice import ( "fmt" "math" + "reflect" ) func ExampleContain() { @@ -526,3 +527,232 @@ func ExampleUpdateAt() { // [a b 1] // [a b c] } + +func ExampleUnique() { + result := Unique([]string{"a", "a", "b"}) + fmt.Println(result) + + // Output: + // [a b] +} + +func ExampleUniqueBy() { + nums := []int{1, 2, 3, 4, 5, 6} + result := UniqueBy(nums, func(val int) int { + return val % 3 + }) + + fmt.Println(result) + + // Output: + // [1 2 0] +} + +func ExampleUnion() { + nums1 := []int{1, 3, 4, 6} + nums2 := []int{1, 2, 5, 6} + + result := Union(nums1, nums2) + + fmt.Println(result) + + // Output: + // [1 3 4 6 2 5] +} + +func ExampleUnionBy() { + nums := []int{1, 2, 3, 4} + + divideTwo := func(n int) int { + return n / 2 + } + result := UnionBy(divideTwo, nums) + + fmt.Println(result) + + // Output: + // [1 2 4] +} + +func ExampleMerge() { + nums1 := []int{1, 2, 3} + nums2 := []int{3, 4} + + result := Merge(nums1, nums2) + + fmt.Println(result) + + // Output: + // [1 2 3 3 4] +} + +func ExampleIntersection() { + nums1 := []int{1, 2, 3} + nums2 := []int{2, 3, 4} + + result := Intersection(nums1, nums2) + + fmt.Println(result) + + // Output: + // [2 3] +} + +func ExampleSymmetricDifference() { + nums1 := []int{1, 2, 3} + nums2 := []int{1, 2, 4} + + result := SymmetricDifference(nums1, nums2) + + fmt.Println(result) + + // Output: + // [3 4] +} + +func ExampleReverse() { + strs := []string{"a", "b", "c", "d"} + + Reverse(strs) + + fmt.Println(strs) + + // Output: + // [d c b a] +} + +func ExampleSort() { + nums := []int{1, 4, 3, 2, 5} + + Sort(nums) + + fmt.Println(nums) + + // Output: + // [1 2 3 4 5] +} + +func ExampleSortBy() { + type User struct { + Name string + Age uint + } + + users := []User{ + {Name: "a", Age: 21}, + {Name: "b", Age: 15}, + {Name: "c", Age: 100}} + + SortBy(users, func(a, b User) bool { + return a.Age < b.Age + }) + + fmt.Println(users) + + // Output: + // [{b 15} {a 21} {c 100}] +} + +func ExampleSortByField() { + type User struct { + Name string + Age uint + } + + users := []User{ + {Name: "a", Age: 21}, + {Name: "b", Age: 15}, + {Name: "c", Age: 100}} + + SortByField(users, "Age", "desc") + + fmt.Println(users) + + // Output: + // [{c 100} {a 21} {b 15}] +} + +func ExampleWithout() { + result := Without([]int{1, 2, 3, 4}, 1, 2) + + fmt.Println(result) + + // Output: + // [3 4] +} + +func ExampleIndexOf() { + strs := []string{"a", "a", "b", "c"} + + result1 := IndexOf(strs, "a") + result2 := IndexOf(strs, "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // -1 +} + +func ExampleLastIndexOf() { + strs := []string{"a", "a", "b", "c"} + + result1 := LastIndexOf(strs, "a") + result2 := LastIndexOf(strs, "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // -1 +} + +func ExampleToSlice() { + result := ToSlice("a", "b", "c") + + fmt.Println(result) + + // Output: + // [a b c] +} + +func ExampleToSlicePointer() { + str1 := "a" + str2 := "b" + + result := ToSlicePointer(str1, str2) + + expect := []*string{&str1, &str2} + + isEqual := reflect.DeepEqual(result, expect) + + fmt.Println(isEqual) + + // Output: + // true +} + +func ExampleAppendIfAbsent() { + result1 := AppendIfAbsent([]string{"a", "b"}, "b") + result2 := AppendIfAbsent([]string{"a", "b"}, "c") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [a b] + // [a b c] +} + +func ExampleKeyBy() { + result := KeyBy([]string{"a", "ab", "abc"}, func(str string) int { + return len(str) + }) + + fmt.Println(result) + + // Output: + // map[1:a 2:ab 3:abc] +}