Skip to content

Commit 3e7413d

Browse files
committed
feat: add issContainsElement function.
1 parent 0b5c9f0 commit 3e7413d

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

util.go

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,54 @@ func isComparable(v any) bool {
6262
}
6363
}
6464

65+
// isContainsElement checks whether the array or slice contains the specific element or not. It'll
66+
// panic if the source is not an array or a slice, and it'll also panic if the element's type is
67+
// not the same as the source's element.
68+
func isContainsElement(source, elem any) bool {
69+
st := reflect.ValueOf(source)
70+
if st.Kind() == reflect.Ptr {
71+
st = st.Elem()
72+
}
73+
if st.Kind() != reflect.Array && st.Kind() != reflect.Slice {
74+
panic("require array or slice")
75+
}
76+
if ok, isMixed := isSameType(st.Type().Elem(), reflect.TypeOf(elem)); !ok && !isMixed {
77+
panic("require same type")
78+
}
79+
80+
if st.Len() == 0 {
81+
return false
82+
}
83+
84+
ev := reflect.ValueOf(elem)
85+
86+
for i := 0; i < st.Len(); i++ {
87+
ok := isEqual(st.Index(i), ev)
88+
if ok {
89+
return true
90+
}
91+
}
92+
return false
93+
}
94+
6595
// isEqual checks the equality of the values.
6696
func isEqual(x, y any) bool {
6797
if x == nil || y == nil {
6898
return x == y
6999
}
70-
v1 := reflect.ValueOf(x)
71-
v2 := reflect.ValueOf(y)
100+
101+
var v1, v2 reflect.Value
102+
if xv, ok := x.(reflect.Value); ok {
103+
v1 = xv
104+
} else {
105+
v1 = reflect.ValueOf(x)
106+
}
107+
if yv, ok := y.(reflect.Value); ok {
108+
v2 = yv
109+
} else {
110+
v2 = reflect.ValueOf(y)
111+
}
112+
72113
if isSame, isMixSign := isSameType(v1.Type(), v2.Type()); !isSame {
73114
if isMixSign {
74115
return isEqualForMixSignInt(v1, v2)
@@ -86,6 +127,8 @@ func isEqual(x, y any) bool {
86127
return v1.Float() == v2.Float()
87128
case reflect.Complex64, reflect.Complex128:
88129
return v1.Complex() == v2.Complex()
130+
case reflect.String:
131+
return v1.String() == v2.String()
89132
case reflect.Slice:
90133
return isSliceEqual(v1, v2)
91134
default:

util_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,30 @@ func TestFailedHandler(t *testing.T) {
2323
assert.DeepEqual(isTerminated, true)
2424
}
2525

26+
func TestIsContainsElement(t *testing.T) {
27+
assert := New(t)
28+
29+
assert.PanicNow(func() {
30+
isContainsElement("not array or slice", 1)
31+
})
32+
assert.PanicNow(func() {
33+
isContainsElement([]string{"a", "b", "c"}, 1)
34+
})
35+
36+
assert.NotTrueNow(isContainsElement([]string{}, "c"))
37+
assert.TrueNow(isContainsElement([]string{"a", "b", "c"}, "c"))
38+
assert.NotTrueNow(isContainsElement([]string{"a", "b", "c"}, "d"))
39+
assert.TrueNow(isContainsElement([]int{1, 2, 3}, 3))
40+
assert.NotTrueNow(isContainsElement([]int{1, 2, 3}, 4))
41+
assert.TrueNow(isContainsElement([]int64{1, 2, 3}, 3))
42+
assert.NotTrueNow(isContainsElement([]int64{1, 2, 3}, 4))
43+
assert.TrueNow(isContainsElement([]uint64{1, 2, 3}, 3))
44+
assert.NotTrueNow(isContainsElement([]uint64{1, 2, 3}, 4))
45+
assert.TrueNow(isContainsElement(&[]int{1, 2, 3}, 3))
46+
assert.TrueNow(isContainsElement([3]int{1, 2, 3}, 3))
47+
assert.NotTrueNow(isContainsElement([3]int{1, 2, 3}, 4))
48+
}
49+
2650
func TestIsEqual(t *testing.T) {
2751
assert := New(t)
2852

0 commit comments

Comments
 (0)