diff --git a/slice/add_test.go b/slice/add_test.go index 014a9df..078d2b3 100644 --- a/slice/add_test.go +++ b/slice/add_test.go @@ -24,7 +24,7 @@ import ( ) func TestAdd(t *testing.T) { - // Delete 主要依赖于 internal/slice.Delete 来保证正确性 + // Add 主要依赖于 internal/slice.Add 来保证正确性 testCases := []struct { name string slice []int diff --git a/slice/intersect.go b/slice/intersect.go index f82edef..6ba4505 100644 --- a/slice/intersect.go +++ b/slice/intersect.go @@ -33,12 +33,11 @@ func IntersectSet[T comparable](src []T, dst []T) []T { // 已去重 func IntersectSetFunc[T any](src []T, dst []T, equal equalFunc[T]) []T { var ret = make([]T, 0, len(src)) - for _, valSrc := range src { - for _, valDst := range dst { - if equal(valDst, valSrc) { - ret = append(ret, valSrc) - break - } + for _, v := range dst { + if ContainsFunc[T](src, func(t T) bool { + return equal(t, v) + }) { + ret = append(ret, v) } } return deduplicateFunc[T](ret, equal) diff --git a/slice/symmetric_diff.go b/slice/symmetric_diff.go index d3bd1e9..f31dab8 100644 --- a/slice/symmetric_diff.go +++ b/slice/symmetric_diff.go @@ -19,60 +19,45 @@ package slice // 返回值的元素顺序是不定的 func SymmetricDiffSet[T comparable](src, dst []T) []T { srcMap, dstMap := toMap[T](src), toMap[T](dst) - for dstKey := range dstMap { - if _, exist := srcMap[dstKey]; exist { - // 删除共同元素,两者剩余的并集即为对称差 - delete(dstMap, dstKey) - delete(srcMap, dstKey) + for k := range dstMap { + if _, ok := srcMap[k]; ok { + delete(srcMap, k) + } else { + srcMap[k] = struct{}{} } } - for k, v := range dstMap { - srcMap[k] = v - } - var ret = make([]T, 0, len(srcMap)) + res := make([]T, 0, len(srcMap)) for k := range srcMap { - ret = append(ret, k) + res = append(res, k) } - return ret + return res } // SymmetricDiffSetFunc 对称差集 // 你应该优先使用 SymmetricDiffSet // 已去重 func SymmetricDiffSetFunc[T any](src, dst []T, equal equalFunc[T]) []T { - var interSection = make([]T, 0, min(len(src), len(dst))) - for _, valSrc := range src { - for _, valDst := range dst { - if equal(valSrc, valDst) { - interSection = append(interSection, valSrc) - break - } - } - } + res := []T{} - ret := make([]T, 0, len(src)+len(dst)-len(interSection)*2) + //找出在src不在dst的元素 for _, v := range src { - if !ContainsFunc[T](interSection, func(src T) bool { - return equal(src, v) + if !ContainsFunc[T](dst, func(t T) bool { + return equal(t, v) }) { - ret = append(ret, v) + res = append(res, v) } } + + //找出在dst不在src的元素 for _, v := range dst { - if !ContainsFunc[T](interSection, func(src T) bool { - return equal(src, v) + if !ContainsFunc[T](src, func(t T) bool { + return equal(t, v) }) { - ret = append(ret, v) + res = append(res, v) } } - return deduplicateFunc[T](ret, equal) -} -func min(src, dst int) int { - if src > dst { - return dst - } - return src + return deduplicateFunc[T](res, equal) } diff --git a/slice/symmetric_diff_test.go b/slice/symmetric_diff_test.go index 7ba0f9d..59060c7 100644 --- a/slice/symmetric_diff_test.go +++ b/slice/symmetric_diff_test.go @@ -30,31 +30,70 @@ func TestSymmetricDiffSet(t *testing.T) { want []int }{ { - src: []int{1, 2, 4, 3}, - dst: []int{4, 5, 6, 1}, - want: []int{2, 3, 5, 6}, - name: "normal test", + name: "no inter", + src: []int{1, 2, 3}, + dst: []int{4, 5, 6}, + want: []int{1, 2, 3, 4, 5, 6}, }, { - src: []int{1, 1, 2, 3, 4}, - dst: []int{4, 5, 6, 1, 7, 6}, - want: []int{3, 6, 7, 5, 2}, - name: "deduplicate", + name: "part inter", + src: []int{1, 2, 3}, + dst: []int{3, 4, 5}, + want: []int{1, 2, 4, 5}, }, { - src: []int{}, - dst: []int{1}, + name: "src contain dst", + src: []int{1, 2, 3}, + dst: []int{2, 3}, want: []int{1}, - name: "src length is 0", }, { - src: []int{1, 3, 5}, - dst: []int{2, 4}, - want: []int{1, 3, 2, 4, 5}, - name: "not exist same ele", + name: "dst contain src", + src: []int{4}, + dst: []int{4, 5, 6}, + want: []int{5, 6}, + }, + { + name: "equal", + src: []int{1, 2, 3}, + dst: []int{1, 2, 3}, + want: []int{}, + }, + { + name: "dst empty", + src: []int{1, 2, 3}, + dst: []int{}, + want: []int{1, 2, 3}, + }, + { + name: "src empty", + src: []int{}, + dst: []int{4, 5, 6}, + want: []int{4, 5, 6}, + }, + { + name: "all empty", + src: []int{}, + dst: []int{}, + want: []int{}, + }, + { + name: "src nil", + src: nil, + dst: []int{4, 5, 6}, + want: []int{4, 5, 6}, + }, + { + name: "dst nil", + src: []int{4, 5, 6}, + dst: nil, + want: []int{4, 5, 6}, }, { name: "both nil", + src: nil, + dst: nil, + want: []int{}, }, } for _, tt := range tests { @@ -73,31 +112,70 @@ func TestSymmetricDiffSetFunc(t *testing.T) { want []int }{ { - src: []int{1, 2, 3, 4}, - dst: []int{4, 5, 6, 1}, - want: []int{2, 3, 5, 6}, - name: "normal test", + name: "no inter", + src: []int{1, 2, 3}, + dst: []int{4, 5, 6}, + want: []int{1, 2, 3, 4, 5, 6}, }, { - src: []int{1, 1, 2, 3, 4}, - dst: []int{4, 5, 6, 1, 7, 6}, - want: []int{3, 6, 7, 5, 2}, - name: "deduplicate", + name: "part inter", + src: []int{1, 2, 3}, + dst: []int{3, 4, 5}, + want: []int{1, 2, 4, 5}, }, { - src: []int{}, - dst: []int{1}, + name: "src contain dst", + src: []int{1, 2, 3}, + dst: []int{2, 3}, want: []int{1}, - name: "src length is 0", }, { - src: []int{1, 3, 5}, - dst: []int{2, 4}, - want: []int{1, 3, 2, 4, 5}, - name: "not exist same ele", + name: "dst contain src", + src: []int{4}, + dst: []int{4, 5, 6}, + want: []int{5, 6}, + }, + { + name: "equal", + src: []int{1, 2, 3}, + dst: []int{1, 2, 3}, + want: []int{}, + }, + { + name: "dst empty", + src: []int{1, 2, 3}, + dst: []int{}, + want: []int{1, 2, 3}, + }, + { + name: "src empty", + src: []int{}, + dst: []int{4, 5, 6}, + want: []int{4, 5, 6}, + }, + { + name: "all empty", + src: []int{}, + dst: []int{}, + want: []int{}, + }, + { + name: "src nil", + src: nil, + dst: []int{4, 5, 6}, + want: []int{4, 5, 6}, + }, + { + name: "dst nil", + src: []int{4, 5, 6}, + dst: nil, + want: []int{4, 5, 6}, }, { name: "both nil", + src: nil, + dst: nil, + want: []int{}, }, } for _, tt := range tests {