github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekaarr/slice_test.go (about) 1 package ekaarr_test 2 3 import ( 4 "reflect" 5 "testing" 6 "unsafe" 7 8 "github.com/stretchr/testify/require" 9 10 "github.com/qioalice/ekago/v3/ekaarr" 11 ) 12 13 func slicePtr[T comparable](in []T) uintptr { 14 return (*reflect.SliceHeader)(unsafe.Pointer(&in)).Data 15 } 16 17 func TestFilter(t *testing.T) { 18 19 var in = []int{1, 2, 3, 4, -1, 0, -2, -5} 20 var out = []int{1, 2, 3, 4} 21 var got = ekaarr.Filter(in, func(n int) bool { return n > 0 }) 22 23 require.Equal(t, out, got) 24 require.Equal(t, slicePtr(in), slicePtr(got)) 25 26 in = []int{1, 2, 3, 4} 27 out = []int{1, 2, 3, 4} 28 got = ekaarr.Filter(in, func(n int) bool { return n > 0 }) 29 30 require.Equal(t, out, got) 31 require.Equal(t, slicePtr(in), slicePtr(got)) 32 33 in = []int{-1, -2, -3, 0, -3, -2, -1} 34 out = []int{} 35 got = ekaarr.Filter(in, func(n int) bool { return n > 0 }) 36 37 require.Equal(t, out, got) 38 39 in = []int{1, -1, 2, 3, -1, -2, -3, 4, -5, -6, 5, 6, 7} 40 out = []int{1, 2, 3, 4, 5, 6, 7} 41 got = ekaarr.Filter(in, func(n int) bool { return n > 0 }) 42 43 require.Equal(t, out, got) 44 } 45 46 func BenchmarkFilter(b *testing.B) { 47 48 var bg = func(in []int, cb func(int) bool) func(*testing.B) { 49 return func(b *testing.B) { 50 b.ReportAllocs() 51 for i := 0; i < b.N; i++ { 52 _ = ekaarr.Filter(in, cb) 53 } 54 } 55 } 56 57 var f = func(n int) bool { return n > 0 } 58 59 var in1 = []int{1, 2, 3, 4, -1, 0, -2, -5} 60 var in2 = []int{1, 2, 3, 4} 61 var in3 = []int{-1, -2, -3, 0, -3, -2, -1} 62 var in4 = []int{1, -1, 2, 3, -1, -2, -3, 4, -5, -6, 5, 6, 7} 63 64 var mul = func(in []int, n int) []int { 65 var out = make([]int, 0, len(in)*n) 66 for i := 0; i < n; i++ { 67 out = append(out, in...) 68 } 69 return out 70 } 71 72 var sort = func(in []int) []int { 73 var pos []int 74 var neg []int 75 for i, n := 0, len(in); i < n; i++ { 76 if in[i] > 0 { 77 pos = append(pos, in[i]) 78 } else { 79 neg = append(neg, in[i]) 80 } 81 } 82 return append(pos, neg...) 83 } 84 85 b.Run("TrimRight", bg(in1, f)) 86 b.Run("NoFilter", bg(in2, f)) 87 b.Run("FilterAll", bg(in3, f)) 88 b.Run("Common", bg(in4, f)) 89 90 b.Run("TrimRight-x10", bg(sort(mul(in1, 10)), f)) 91 b.Run("NoFilter-x10", bg(mul(in2, 10), f)) 92 b.Run("FilterAll-x10", bg(mul(in3, 10), f)) 93 b.Run("Common-x10", bg(mul(in4, 10), f)) 94 95 b.Run("TrimRight-x100", bg(sort(mul(in1, 100)), f)) 96 b.Run("NoFilter-x100", bg(mul(in2, 100), f)) 97 b.Run("FilterAll-x100", bg(mul(in3, 100), f)) 98 b.Run("Common-x100", bg(mul(in4, 100), f)) 99 } 100 101 func TestContains(t *testing.T) { 102 103 for _, tc := range []struct { 104 In1, In2 []int 105 Any, All bool 106 }{ 107 {[]int{1, 2, 3, 4}, []int{1}, true, true}, 108 {[]int{1, 2, 3, 4}, []int{2, 5}, true, false}, 109 {[]int{1, 2, 3, 4}, []int{}, false, false}, 110 {[]int{1, 2, 3, 4}, []int{1, 4}, true, true}, 111 {[]int{1, 2, 3, 4}, []int{2, 3}, true, true}, 112 {[]int{1, 2, 3, 4}, []int{0, 1}, true, false}, 113 {[]int{1, 2, 3, 4}, []int{4, 5}, true, false}, 114 {[]int{1, 2, 3, 4}, []int{1, 2, 3, 4}, true, true}, 115 {[]int{}, []int{1, 2}, false, false}, 116 {[]int{}, []int{}, false, false}, 117 {[]int{1}, []int{1}, true, true}, 118 {[]int{1}, []int{1, 2}, true, false}, 119 {[]int{1, 2}, []int{1}, true, true}, 120 {[]int{1, 2}, []int{2}, true, true}, 121 {[]int{1, 2}, []int{3}, false, false}, 122 } { 123 const F1 = "[ANY] In1: %v, In2: %v\n" 124 const F2 = "[ALL] In1: %v, In2: %v\n" 125 126 var r = ekaarr.ContainsAny(tc.In1, tc.In2...) 127 require.Equalf(t, tc.Any, r, F1, tc.In1, tc.In2) 128 129 r = ekaarr.ContainsAll(tc.In1, tc.In2...) 130 require.Equalf(t, tc.All, r, F2, tc.In1, tc.In2) 131 } 132 } 133 134 func TestReduce(t *testing.T) { 135 136 var in = []int{1, 2, 3, 4, 5} 137 var sum = 0 138 var mul = 1 139 140 for i, n := 0, len(in); i < n; i++ { 141 sum += in[i] 142 mul *= in[i] 143 } 144 145 var sumCb = func(acc int, v int, _ int, _ []int) int { return acc + v } 146 var mulCb = func(acc int, v int, _ int, _ []int) int { return acc * v } 147 148 require.Equal(t, sum, ekaarr.Reduce(in, 0, sumCb)) 149 require.Equal(t, mul, ekaarr.Reduce(in, 1, mulCb)) 150 } 151 152 func TestRemove(t *testing.T) { 153 154 for _, tc := range []struct { 155 In1, In2, Out []int 156 }{ 157 {[]int{1, 2, 3, 4}, []int{1, 2}, []int{3, 4}}, 158 {[]int{1, 2, 3, 4}, []int{1, 2, 3, 4}, []int{}}, 159 {[]int{1, 2, 3, 4}, []int{}, []int{1, 2, 3, 4}}, 160 {[]int{1, 2, 3, 4}, []int{1}, []int{2, 3, 4}}, 161 } { 162 const F = "In1: %v, In2: %v\n" 163 164 var r = ekaarr.Remove(tc.In1, tc.In2...) 165 require.Equalf(t, tc.Out, r, F, tc.In1, tc.In2) 166 } 167 } 168 169 func TestUnique(t *testing.T) { 170 171 for _, tc := range []struct { 172 In, Out []int 173 }{ 174 {[]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}}, 175 {[]int{1, 2}, []int{1, 2}}, 176 {[]int{1}, []int{1}}, 177 {[]int{1, 1}, []int{}}, 178 {[]int{1, 2, 3, 2}, []int{1, 3}}, 179 {[]int{1, 2, 2, 1}, []int{}}, 180 {[]int{1, 2, 3, 1}, []int{2, 3}}, 181 {[]int{1, 1, 1, 1, 4}, []int{4}}, 182 } { 183 const F = "In1: %v\n" 184 185 var in = append(tc.In[:0:0], tc.In...) 186 require.ElementsMatchf(t, tc.Out, ekaarr.Unique(tc.In), F, in) 187 } 188 } 189 190 func TestDistinct(t *testing.T) { 191 192 for _, tc := range []struct { 193 In, Out []int 194 }{ 195 {[]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}}, 196 {[]int{1, 2}, []int{1, 2}}, 197 {[]int{1}, []int{1}}, 198 {[]int{1, 1}, []int{1}}, 199 {[]int{1, 2, 3, 2}, []int{1, 2, 3}}, 200 {[]int{1, 2, 2, 1}, []int{1, 2}}, 201 {[]int{1, 2, 3, 1}, []int{1, 2, 3}}, 202 {[]int{1, 1, 1, 1, 4}, []int{1, 4}}, 203 } { 204 const F = "In1: %v\n" 205 206 require.ElementsMatchf(t, tc.Out, ekaarr.Distinct(tc.In), F, tc.In) 207 } 208 }