Passed
Pull Request — master (#83)
by ertugrul
02:10
created

find.go   A

Size/Duplication

Total Lines 22
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
dl 0
loc 22
rs 10
c 0
b 0
f 0
1
package gotil
2
3
// FindBy iterates over elements of collection, returns an object of fist element predicate if returns true for.
4
//	data := []int64{-100, -5, 30, 100}
5
//	newData, _ := FindBy(data, func(val interface{}, i int) bool {
6
//	if val.(int64) == 30 {
7
// 			return true
8
// 		} else {
9
// 			return false
10
// 		}
11
// 	})
12
// 	// Output: 30
13
func FindBy[T any](s []T, f func(val T) bool) T {
14
	return FindByFromIndex(s, f, 0)
15
}
16
17
// FindByFromIndex iterates over elements of collection, returns an object of fist element predicate if returns true for.
18
// It works same as FindBy just from parameter provides to set start index of given slice or array.
19
func FindByFromIndex[T any](s []T, f func(val T) bool, from int) T {
20
	var result T
21
	index := findIndex(s, f, 0)
22
	if index > -1 {
23
		return s[index]
24
	}
25
	return result
26
}
27
28
// FindLastBy iterates over elements of collection, returns an object of lastest element predicate if returns true for.
29
// 	data := []int64{-100, -5, 30, 100}
30
// 	newData, _ := FindLastBy(data, func(val interface{}, i int) bool {
31
// 		if val.(int64) == 30 {
32
// 			return true
33
// 		} else {
34
// 			return false
35
// 		}
36
// 	})
37
// 	// Output: 30
38
func FindLastBy[T any](s []T, f func(val T) bool) T {
39
	return FindLastByFromIndex(s, f, 0)
40
}
41
42
// FindLastBy iterates over elements of collection, returns an object of lastest element predicate if returns true for.
43
// It works same as FindLastBy just from parameter provides to set start index of given slice or array.
44
func FindLastByFromIndex[T any](s []T, f func(val T) bool, from int) T {
45
	var result T
46
	index := findLastIndex(s, f, 0)
47
	if index > -1 {
48
		return s[index]
49
	}
50
	return result
51
}
52
53
func findIndex[T any](s []T, f func(val T) bool, from int) int {
54
	length := len(s)
55
	if length == 0 {
56
		return -1
57
	}
58
	index := 0
59
	if from < 0 {
60
		index = max(length+index, 0)
61
	} else {
62
		index = min(index, length-1)
63
	}
64
	return baseFindIndex(s, f, index, false)
65
}
66
67
func findLastIndex[T any](s []T, f func(val T) bool, from int) int {
68
	length := len(s)
69
	if length == 0 {
70
		return -1
71
	}
72
	index := length - 1
73
	if from < 0 {
74
		index = max(length+index, 0)
75
	} else {
76
		index = min(index, length-1)
77
	}
78
	return baseFindIndex(s, f, index, true)
79
}
80
81
func baseFindIndex[T any](s []T, f func(val T) bool, from int, right bool) int {
82
	length := len(s)
83
	index := from
84
	if right {
85
		for index < length {
86
			value := s[index]
87
			if f(value) {
88
				return index
89
			}
90
			index--
91
		}
92
	} else {
93
		for index < length {
94
			value := s[index]
95
			if f(value) {
96
				return index
97
			}
98
			index++
99
		}
100
	}
101
	return -1
102
}
103
104
func max(a, b int) int {
105
	if a > b {
106
		return a
107
	}
108
	return b
109
}
110
func min(a, b int) int {
111
	if a < b {
112
		return a
113
	}
114
	return b
115
}
116