github.com/hamba/slices@v0.2.1-0.20220316050741-75c057d92699/intersect_test.go (about) 1 package slices_test 2 3 import ( 4 "testing" 5 6 "github.com/hamba/slices" 7 "github.com/stretchr/testify/assert" 8 ) 9 10 func TestIntersect(t *testing.T) { 11 tests := []struct { 12 name string 13 slice interface{} 14 other interface{} 15 want interface{} 16 }{ 17 { 18 name: "string contains", 19 slice: []string{"foo", "bar", "baz", "bat"}, 20 other: []string{"bar", "baz", "test"}, 21 want: []string{"bar", "baz"}, 22 }, 23 { 24 name: "int contains", 25 slice: []int{1, 2, 3, 4}, 26 other: []int{2, 3, 5}, 27 want: []int{2, 3}, 28 }, 29 { 30 name: "int8 contains", 31 slice: []int8{1, 2, 3, 4}, 32 other: []int8{2, 3, 5}, 33 want: []int8{2, 3}, 34 }, 35 { 36 name: "int16 contains", 37 slice: []int16{1, 2, 3, 4}, 38 other: []int16{2, 3, 5}, 39 want: []int16{2, 3}, 40 }, 41 { 42 name: "int32 contains", 43 slice: []int32{1, 2, 3, 4}, 44 other: []int32{2, 3, 5}, 45 want: []int32{2, 3}, 46 }, 47 { 48 name: "int64 contains", 49 slice: []int64{1, 2, 3, 4}, 50 other: []int64{2, 3, 5}, 51 want: []int64{2, 3}, 52 }, 53 { 54 name: "uint contains", 55 slice: []uint{1, 2, 3, 4}, 56 other: []uint{2, 3, 5}, 57 want: []uint{2, 3}, 58 }, 59 { 60 name: "uint8 contains", 61 slice: []uint8{1, 2, 3, 4}, 62 other: []uint8{2, 3, 5}, 63 want: []uint8{2, 3}, 64 }, 65 { 66 name: "uint16 contains", 67 slice: []uint16{1, 2, 3, 4}, 68 other: []uint16{2, 3, 5}, 69 want: []uint16{2, 3}, 70 }, 71 { 72 name: "uint32 contains", 73 slice: []uint32{1, 2, 3, 4}, 74 other: []uint32{2, 3, 5}, 75 want: []uint32{2, 3}, 76 }, 77 { 78 name: "uint64 contains", 79 slice: []uint64{1, 2, 3, 4}, 80 other: []uint64{2, 3, 5}, 81 want: []uint64{2, 3}, 82 }, 83 { 84 name: "float32 contains", 85 slice: []float32{1, 2, 3, 4}, 86 other: []float32{2, 3, 5}, 87 want: []float32{2, 3}, 88 }, 89 { 90 name: "float64 contains", 91 slice: []float64{1, 2, 3, 4}, 92 other: []float64{2, 3, 5}, 93 want: []float64{2, 3}, 94 }, 95 } 96 97 for _, tt := range tests { 98 t.Run(tt.name, func(t *testing.T) { 99 got := slices.Intersect(tt.slice, tt.other) 100 101 assert.Equal(t, tt.want, got) 102 }) 103 } 104 } 105 106 func TestIntersect_ChecksSliceType(t *testing.T) { 107 assert.Panics(t, func() { 108 slices.Intersect("test", "test") 109 }) 110 } 111 112 func TestIntersect_ChecksValType(t *testing.T) { 113 assert.Panics(t, func() { 114 slices.Intersect([]string{"test"}, 1) 115 }) 116 } 117 118 func BenchmarkIntersect(b *testing.B) { 119 slice := []string{"foo", "bar", "baz", "bat"} 120 other := []string{"bar", "baz", "test"} 121 122 b.ReportAllocs() 123 b.ResetTimer() 124 for i := 0; i < b.N; i++ { 125 slices.Intersect(slice, other) 126 } 127 } 128 129 func intersect(slice, other []string) interface{} { 130 s := make([]string, len(slice)) 131 copy(s, slice) 132 for i := 0; i < len(s); i++ { 133 found := false 134 for _, v := range other { 135 if v == s[i] { 136 found = true 137 break 138 } 139 } 140 if !found { 141 s = append(s[:i], s[i+1:]...) 142 i-- 143 } 144 } 145 return s 146 } 147 148 func BenchmarkIntersectNative(b *testing.B) { 149 slice := []string{"foo", "bar", "baz", "bat"} 150 other := []string{"bar", "baz", "test"} 151 152 b.ReportAllocs() 153 b.ResetTimer() 154 for i := 0; i < b.N; i++ { 155 intersect(slice, other) 156 } 157 }