Skip to content

Commit

Permalink
Merge pull request #44 from ccpwcn/dev
Browse files Browse the repository at this point in the history
切片相关功能增强
  • Loading branch information
ccpwcn authored Jan 4, 2024
2 parents 8795f85 + 4770179 commit 0cb538f
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
- Contains 包含某个元素
- ContainsAll 包含指定元素
- ContainsAny 包含任意元素
- SameElements 两个切片是否拥有相同的元素,不考虑顺序,元素相同即可
- Intersection 两个切片的交集
- Union 两个切片的合集,如果遇到重复元素,只保留1个
- Diff 两个切片的差集,以第一个参数为基准
- [x] 结构体相关操作
- JoinStructsField 将任意结构体切片中的指定字段的值使用英文逗号拼接成一个字符串,例如:用户列表中,所有用户ID拼成一个字符串
- PickStructsField 将任意结构体切片中的指定字段的值提取出来形成一个保持原类型的数组,例如:用户列表中,所有用户ID提取成一个用户ID数组
Expand Down
63 changes: 63 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,66 @@ func ContainsAny[T any](data []T, elements []T) bool {
}
return false
}

// SameElements 两个切片是否拥有相同的元素,不考虑它们的顺序,只要元素相同即可
func SameElements[T any](data1, data2 []T) bool {
if len(data1) != len(data2) {
return false
}
for _, datum1 := range data1 {
found := false
for _, datum2 := range data2 {
if reflect.DeepEqual(datum1, datum2) {
found = true
break
}
}
if !found {
return false
}
}
return true
}

// Intersection 两个切片的交集
func Intersection[T any](s1, s2 []T) (results []T) {
hash := make(map[any]bool)
for _, elem := range s1 {
hash[elem] = true
}
for _, elem := range s2 {
if hash[elem] {
results = append(results, elem)
}
}
return results
}

// Union 两个切片的合集,如果遇到重复元素,只保留1个
func Union[T any](s1, s2 []T) (results []T) {
hash := make(map[any]bool)
for _, elem := range s1 {
hash[elem] = true
}
for _, elem := range s2 {
hash[elem] = true
}
for elem := range hash {
results = append(results, elem.(T))
}
return results
}

// Diff 两个切片的差集,以第一个参数s1为基准,即:返回在s1中存在 且 在s2中不存在的元素集合
func Diff[T any](s1, s2 []T) (results []T) {
hash := make(map[any]bool)
for _, elem := range s2 {
hash[elem] = true
}
for _, elem := range s1 {
if !hash[elem] {
results = append(results, elem)
}
}
return results
}
68 changes: 68 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,71 @@ func TestContainsAnyInteger(t *testing.T) {
})
}
}

func TestSlice_Intersection_Union_Diff_Integer(t *testing.T) {
type args[T any] struct {
data1 []T
data2 []T
}
type testCase[T any] struct {
name string
args args[T]
intersectionWant []T
unionWant []T
diffWant []T
}
tests := []testCase[int]{
{
name: "SliceIntersection_Union_Diff_Integer",
args: args[int]{data1: []int{1, 2, 3, 4}, data2: []int{1, 2, 8, 10}},
intersectionWant: []int{1, 2},
unionWant: []int{1, 2, 3, 4, 8, 10},
diffWant: []int{3, 4},
},
}
for _, tt := range tests {
if got := Intersection[int](tt.args.data1, tt.args.data2); !SameElements(got, tt.intersectionWant) {
t.Errorf("Intersection() = %v, want %v", got, tt.intersectionWant)
}
if got := Union[int](tt.args.data1, tt.args.data2); !SameElements(got, tt.unionWant) {
t.Errorf("Union() = %v, want %v", got, tt.unionWant)
}
if got := Diff[int](tt.args.data1, tt.args.data2); !SameElements(got, tt.diffWant) {
t.Errorf("Diff() = %v, want %v", got, tt.diffWant)
}
}
}

func TestSlice_Intersection_Union_Diff_String(t *testing.T) {
type args[T any] struct {
data1 []T
data2 []T
}
type testCase[T any] struct {
name string
args args[T]
intersectionWant []T
unionWant []T
diffWant []T
}
tests := []testCase[string]{
{
name: "SliceIntersection_Union_Diff_String",
args: args[string]{data1: []string{"1", "2", "3", "4"}, data2: []string{"1", "2", "8", "10"}},
intersectionWant: []string{"1", "2"},
unionWant: []string{"1", "2", "3", "4", "8", "10"},
diffWant: []string{"3", "4"},
},
}
for _, tt := range tests {
if got := Intersection[string](tt.args.data1, tt.args.data2); !SameElements(got, tt.intersectionWant) {
t.Errorf("Intersection() = %v, want %v", got, tt.intersectionWant)
}
if got := Union[string](tt.args.data1, tt.args.data2); !SameElements(got, tt.unionWant) {
t.Errorf("Union() = %v, want %v", got, tt.unionWant)
}
if got := Diff[string](tt.args.data1, tt.args.data2); !SameElements(got, tt.diffWant) {
t.Errorf("Diff() = %v, want %v", got, tt.diffWant)
}
}
}

0 comments on commit 0cb538f

Please sign in to comment.