-
Notifications
You must be signed in to change notification settings - Fork 0
/
any.go
83 lines (63 loc) · 1.9 KB
/
any.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package functools
import (
"reflect"
"errors"
)
/*
'Any' function returns 'true' if any element of the iterable 'slice' is 'true'.
If the slice is empty, returns 'false'. Each element of the slice is converted to bool
by 'functools.ToBool' function. Function allows slices and arrays.
Any(slice) bool
AnySafe(slice) (bool, err)
'AnyFunc' function applies 'func' parameter for each element of the iterable 'slice'
and returns 'true' if any result of 'func' calling is 'true'. If the slice is empty,
returns 'false'. Function allows slices and arrays.
AnyFunc(func, slice) bool
AnyFuncSafe(func, slice) (bool, err)
*/
func any(function, slice interface{}) bool {
rv := reflect.ValueOf(slice)
if rv.Kind() != reflect.Slice && rv.Kind() != reflect.Array {
raise(errors.New("The passed collection is not a slice or an array"), "Any")
}
fn := reflect.ValueOf(function)
t := rv.Type().Elem()
if !verifyAnyFuncType(fn, t) {
raise(errors.New("Function must be of type func(" + t.String() +
") bool or func(interface{}) bool"), "Any")
}
var param [1]reflect.Value
for i := 0; i < rv.Len(); i++ {
param[0] = rv.Index(i)
if fn.Call(param[:])[0].Bool() {
return true
}
}
return false
}
func verifyAnyFuncType(fn reflect.Value, elType reflect.Type) bool {
if fn.Kind() != reflect.Func {
return false
}
if fn.Type().NumIn() != 1 || fn.Type().NumOut() != 1 {
return false
}
return ((fn.Type().In(0).Kind() == reflect.Interface || fn.Type().In(0) == elType) &&
fn.Type().Out(0).Kind() == reflect.Bool)
}
func Any(slice interface{}) bool {
return any(ToBool, slice)
}
func AnySafe(slice interface{}) (result bool, err error) {
defer except(&err)
result = any(ToBool, slice)
return
}
func AnyFunc(function, slice interface{}) bool {
return any(function, slice)
}
func AnyFuncSafe(function, slice interface{}) (result bool, err error) {
defer except(&err)
result = any(function, slice)
return
}