Passed
Pull Request — master (#66)
by Hayrullah
56s
created

internal.findIndex   A

Complexity

Conditions 3

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
dl 0
loc 12
rs 9.9
c 0
b 0
f 0
nop 3
1
package internal
2
3
import (
4
	"reflect"
5
6
	"github.com/gotilty/gotil/internal/errs"
7
)
8
9
// FindBy iterates over elements of collection, returns an object of fist element predicate if returns true for.
10
// 		data := []int64{-100, -5, 30, 100}
11
// 		newData, _ := FindBy(data, func(val interface{}, i int) bool {
12
// 			if val.(int64) == 30 {
13
// 				return true
14
// 			} else {
15
// 				return false
16
// 			}
17
// 		})
18
// 		// Output: 30
19
func FindBy(a interface{}, f func(val interface{}, i int) bool) (interface{}, error) {
20
	return FindByFromIndex(a, f, 0)
21
}
22
23
// FindByFromIndex iterates over elements of collection, returns an object of fist element predicate if returns true for.
24
// It works same as FindBy just from parameter provides to set start index of given slice or array.
25
func FindByFromIndex(a interface{}, f func(val interface{}, i int) bool, from int) (interface{}, error) {
26
	val := reflect.ValueOf(a)
27
	switch val.Kind() {
28
	case reflect.Slice, reflect.Array:
29
		index := findIndex(val, f, 0)
30
		if index > -1 {
31
			return val.Index(index).Interface(), nil
32
		}
33
		return nil, nil
34
	}
35
	return nil, errs.NewUnsupportedTypeError(val.Kind().String())
36
}
37
38
func findIndex(val reflect.Value, f func(val interface{}, i int) bool, from int) int {
39
	length := val.Len()
40
	if length == 0 {
41
		return -1
42
	}
43
	index := 0
44
	if from < 0 {
45
		index = max(length+index, 0)
46
	} else {
47
		index = min(index, length-1)
48
	}
49
	return baseFindIndex(val, f, index, false)
50
}
51