diff --git a/README.md b/README.md index 48e563c..20d08ff 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,9 @@ - Empty 判断Set元素是否是空的 - [x] Slice切片相关 - SlicePagination 切片分页,返回一个分好页的二维数组,可指定页大小 + - Contains 包含某个元素 + - ContainsAll 包含指定元素 + - ContainsAny 包含任意元素 - [x] 结构体相关操作 - JoinStructsField 将任意结构体数组中的指定字段的值使用英文逗号拼接成一个字符串,例如:用户列表中,所有用户ID拼成一个字符串 - PickStructsField 将任意结构体数组中的指定字段的值提取出来形成一个保持原类型的数组,例如:用户列表中,所有用户ID提取成一个用户ID数组 diff --git a/slice.go b/slice.go index fddec19..bdeeab8 100644 --- a/slice.go +++ b/slice.go @@ -1,5 +1,10 @@ package kgo +import "reflect" + +type ChsSort interface { +} + // SlicePagination 对一个切片进行内存分页 func SlicePagination[T any](data []T, pageSize int) (paged [][]T) { if data == nil { @@ -26,3 +31,30 @@ func SlicePagination[T any](data []T, pageSize int) (paged [][]T) { } return paged } + +func Contains[T any](data []T, element T) bool { + for _, datum := range data { + if reflect.DeepEqual(datum, element) { + return true + } + } + return false +} + +func ContainsAll[T any](data []T, elements []T) bool { + for _, element := range elements { + if !Contains(data, element) { + return false + } + } + return true +} + +func ContainsAny[T any](data []T, elements []T) bool { + for _, element := range elements { + if Contains(data, element) { + return true + } + } + return false +} diff --git a/slice_test.go b/slice_test.go index 0945cbd..d23b4c4 100644 --- a/slice_test.go +++ b/slice_test.go @@ -49,3 +49,179 @@ func TestSlicePagination(t *testing.T) { }) } } + +func TestContainsString(t *testing.T) { + type args[T any] struct { + data []T + element T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[string]{ + {name: "stringsContains", args: args[string]{data: []string{"abc", "def", "xyz"}, element: "abc"}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Contains(tt.args.data, tt.args.element); got != tt.want { + t.Errorf("Contains() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsInteger(t *testing.T) { + type args[T any] struct { + data []T + element T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[int]{ + {name: "integerContains", args: args[int]{data: []int{1, 2, 3}, element: 1}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Contains(tt.args.data, tt.args.element); got != tt.want { + t.Errorf("Contains() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsFloat(t *testing.T) { + type args[T any] struct { + data []T + element T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[float64]{ + {name: "floatContains", args: args[float64]{data: []float64{1.1, 2.2, 3.3}, element: 1.1}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Contains(tt.args.data, tt.args.element); got != tt.want { + t.Errorf("Contains() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsAllStrings(t *testing.T) { + type args[T any] struct { + data []T + elements []T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[string]{ + {name: "stringsContainsAll", args: args[string]{data: []string{"abc", "def", "xyz"}, elements: []string{"abc", "def"}}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ContainsAll(tt.args.data, tt.args.elements); got != tt.want { + t.Errorf("ContainsAll() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsAllIntegers(t *testing.T) { + type args[T any] struct { + data []T + elements []T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[int]{ + {name: "integerContainsAll", args: args[int]{data: []int{1, 2, 3}, elements: []int{1, 2}}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ContainsAll(tt.args.data, tt.args.elements); got != tt.want { + t.Errorf("ContainsAll() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsAllFloats(t *testing.T) { + type args[T any] struct { + data []T + elements []T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[float64]{ + {name: "floatContainsAll", args: args[float64]{data: []float64{1.1, 2.2, 3.3}, elements: []float64{1.1, 2.2}}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ContainsAll(tt.args.data, tt.args.elements); got != tt.want { + t.Errorf("ContainsAll() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsAnyString(t *testing.T) { + type args[T any] struct { + data []T + elements []T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[string]{ + {name: "stringsContainsAny", args: args[string]{data: []string{"abc", "def", "xyz"}, elements: []string{"abc", "opq"}}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ContainsAny(tt.args.data, tt.args.elements); got != tt.want { + t.Errorf("ContainsAny() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsAnyInteger(t *testing.T) { + type args[T any] struct { + data []T + elements []T + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[int]{ + {name: "integerContainsAny", args: args[int]{data: []int{1, 2, 3, 4}, elements: []int{10, 1, 2, 300}}, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ContainsAny(tt.args.data, tt.args.elements); got != tt.want { + t.Errorf("ContainsAny() = %v, want %v", got, tt.want) + } + }) + } +}