...
1 package funk
2
3 import (
4 "reflect"
5 )
6
7
8 func Subtract(x interface{}, y interface{}) interface{} {
9 if !IsCollection(x) {
10 panic("First parameter must be a collection")
11 }
12 if !IsCollection(y) {
13 panic("Second parameter must be a collection")
14 }
15
16 hash := map[interface{}]struct{}{}
17
18 xValue := reflect.ValueOf(x)
19 xType := xValue.Type()
20
21 yValue := reflect.ValueOf(y)
22 yType := yValue.Type()
23
24 if NotEqual(xType, yType) {
25 panic("Parameters must have the same type")
26 }
27
28 zType := reflect.SliceOf(xType.Elem())
29 zSlice := reflect.MakeSlice(zType, 0, 0)
30
31 for i := 0; i < xValue.Len(); i++ {
32 v := xValue.Index(i).Interface()
33 hash[v] = struct{}{}
34 }
35
36 for i := 0; i < yValue.Len(); i++ {
37 v := yValue.Index(i).Interface()
38 _, ok := hash[v]
39 if ok {
40 delete(hash, v)
41 }
42 }
43
44 for i := 0; i < xValue.Len(); i++ {
45 v := xValue.Index(i).Interface()
46 _, ok := hash[v]
47 if ok {
48 zSlice = reflect.Append(zSlice, xValue.Index(i))
49 }
50 }
51
52 return zSlice.Interface()
53 }
54
55
56 func SubtractString(x []string, y []string) []string {
57 if len(x) == 0 {
58 return []string{}
59 }
60
61 if len(y) == 0 {
62 return x
63 }
64
65 slice := []string{}
66 hash := map[string]struct{}{}
67
68 for _, v := range x {
69 hash[v] = struct{}{}
70 }
71
72 for _, v := range y {
73 _, ok := hash[v]
74 if ok {
75 delete(hash, v)
76 }
77 }
78
79 for _, v := range x {
80 _, ok := hash[v]
81 if ok {
82 slice = append(slice, v)
83 }
84 }
85
86 return slice
87 }
88
View as plain text