1package funk 2 3import ( 4 "reflect" 5) 6 7// Intersect returns the intersection between two collections. 8// 9// Deprecated: use Join(x, y, InnerJoin) instead of Intersect, InnerJoin 10// implements deduplication mechanism, so verify your code behaviour 11// before using it 12func Intersect(x interface{}, y interface{}) interface{} { 13 if !IsCollection(x) { 14 panic("First parameter must be a collection") 15 } 16 if !IsCollection(y) { 17 panic("Second parameter must be a collection") 18 } 19 20 hash := map[interface{}]struct{}{} 21 22 xValue := reflect.ValueOf(x) 23 xType := xValue.Type() 24 25 yValue := reflect.ValueOf(y) 26 yType := yValue.Type() 27 28 if NotEqual(xType, yType) { 29 panic("Parameters must have the same type") 30 } 31 32 zType := reflect.SliceOf(xType.Elem()) 33 zSlice := reflect.MakeSlice(zType, 0, 0) 34 35 for i := 0; i < xValue.Len(); i++ { 36 v := xValue.Index(i).Interface() 37 hash[v] = struct{}{} 38 } 39 40 for i := 0; i < yValue.Len(); i++ { 41 v := yValue.Index(i).Interface() 42 _, ok := hash[v] 43 if ok { 44 zSlice = reflect.Append(zSlice, yValue.Index(i)) 45 } 46 } 47 48 return zSlice.Interface() 49} 50 51// IntersectString returns the intersection between two collections of string. 52func IntersectString(x []string, y []string) []string { 53 if len(x) == 0 || len(y) == 0 { 54 return []string{} 55 } 56 57 set := []string{} 58 hash := map[string]struct{}{} 59 60 for _, v := range x { 61 hash[v] = struct{}{} 62 } 63 64 for _, v := range y { 65 _, ok := hash[v] 66 if ok { 67 set = append(set, v) 68 } 69 } 70 71 return set 72} 73 74// Difference returns the difference between two collections. 75func Difference(x interface{}, y interface{}) (interface{}, interface{}) { 76 if !IsCollection(x) { 77 panic("First parameter must be a collection") 78 } 79 if !IsCollection(y) { 80 panic("Second parameter must be a collection") 81 } 82 83 xValue := reflect.ValueOf(x) 84 xType := xValue.Type() 85 86 yValue := reflect.ValueOf(y) 87 yType := yValue.Type() 88 89 if NotEqual(xType, yType) { 90 panic("Parameters must have the same type") 91 } 92 93 leftType := reflect.SliceOf(xType.Elem()) 94 leftSlice := reflect.MakeSlice(leftType, 0, 0) 95 rightType := reflect.SliceOf(yType.Elem()) 96 rightSlice := reflect.MakeSlice(rightType, 0, 0) 97 98 for i := 0; i < xValue.Len(); i++ { 99 v := xValue.Index(i).Interface() 100 if !Contains(y, v) { 101 leftSlice = reflect.Append(leftSlice, xValue.Index(i)) 102 } 103 } 104 105 for i := 0; i < yValue.Len(); i++ { 106 v := yValue.Index(i).Interface() 107 if !Contains(x, v) { 108 rightSlice = reflect.Append(rightSlice, yValue.Index(i)) 109 } 110 } 111 112 return leftSlice.Interface(), rightSlice.Interface() 113} 114 115// DifferenceString returns the difference between two collections of strings. 116func DifferenceString(x []string, y []string) ([]string, []string) { 117 leftSlice := []string{} 118 rightSlice := []string{} 119 120 for _, v := range x { 121 if !ContainsString(y, v) { 122 leftSlice = append(leftSlice, v) 123 } 124 } 125 126 for _, v := range y { 127 if !ContainsString(x, v) { 128 rightSlice = append(rightSlice, v) 129 } 130 } 131 132 return leftSlice, rightSlice 133} 134 135// DifferenceInt64 returns the difference between two collections of int64s. 136func DifferenceInt64(x []int64, y []int64) ([]int64, []int64) { 137 leftSlice := []int64{} 138 rightSlice := []int64{} 139 140 for _, v := range x { 141 if !ContainsInt64(y, v) { 142 leftSlice = append(leftSlice, v) 143 } 144 } 145 146 for _, v := range y { 147 if !ContainsInt64(x, v) { 148 rightSlice = append(rightSlice, v) 149 } 150 } 151 152 return leftSlice, rightSlice 153} 154 155// DifferenceInt32 returns the difference between two collections of ints32. 156func DifferenceInt32(x []int32, y []int32) ([]int32, []int32) { 157 leftSlice := []int32{} 158 rightSlice := []int32{} 159 160 for _, v := range x { 161 if !ContainsInt32(y, v) { 162 leftSlice = append(leftSlice, v) 163 } 164 } 165 166 for _, v := range y { 167 if !ContainsInt32(x, v) { 168 rightSlice = append(rightSlice, v) 169 } 170 } 171 172 return leftSlice, rightSlice 173} 174 175// DifferenceInt returns the difference between two collections of ints. 176func DifferenceInt(x []int, y []int) ([]int, []int) { 177 leftSlice := []int{} 178 rightSlice := []int{} 179 180 for _, v := range x { 181 if !ContainsInt(y, v) { 182 leftSlice = append(leftSlice, v) 183 } 184 } 185 186 for _, v := range y { 187 if !ContainsInt(x, v) { 188 rightSlice = append(rightSlice, v) 189 } 190 } 191 192 return leftSlice, rightSlice 193} 194 195// DifferenceUInt returns the difference between two collections of uints. 196func DifferenceUInt(x []uint, y []uint) ([]uint, []uint) { 197 leftSlice := []uint{} 198 rightSlice := []uint{} 199 200 for _, v := range x { 201 if !ContainsUInt(y, v) { 202 leftSlice = append(leftSlice, v) 203 } 204 } 205 206 for _, v := range y { 207 if !ContainsUInt(x, v) { 208 rightSlice = append(rightSlice, v) 209 } 210 } 211 212 return leftSlice, rightSlice 213} 214 215// DifferenceUInt32 returns the difference between two collections of uints32. 216func DifferenceUInt32(x []uint32, y []uint32) ([]uint32, []uint32) { 217 leftSlice := []uint32{} 218 rightSlice := []uint32{} 219 220 for _, v := range x { 221 if !ContainsUInt32(y, v) { 222 leftSlice = append(leftSlice, v) 223 } 224 } 225 226 for _, v := range y { 227 if !ContainsUInt32(x, v) { 228 rightSlice = append(rightSlice, v) 229 } 230 } 231 232 return leftSlice, rightSlice 233} 234 235// DifferenceUInt64 returns the difference between two collections of uints64. 236func DifferenceUInt64(x []uint64, y []uint64) ([]uint64, []uint64) { 237 leftSlice := []uint64{} 238 rightSlice := []uint64{} 239 240 for _, v := range x { 241 if !ContainsUInt64(y, v) { 242 leftSlice = append(leftSlice, v) 243 } 244 } 245 246 for _, v := range y { 247 if !ContainsUInt64(x, v) { 248 rightSlice = append(rightSlice, v) 249 } 250 } 251 252 return leftSlice, rightSlice 253} 254