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  }