-
Notifications
You must be signed in to change notification settings - Fork 0
/
slices_scalars.go
110 lines (88 loc) · 2.63 KB
/
slices_scalars.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package generics
import (
"context"
"fmt"
"github.com/zeroflucs-given/generics/filtering"
)
// All returns true if no item in the list fails to meet the predicates. If multiple
// predicates are passed, they are treated as logical AND operations.
func All[T any](items []T, filters ...filtering.Expression[T]) bool {
filter := filtering.And(filters...)
for i, v := range items {
if !filter(i, v) {
return false
}
}
return true
}
// AllWithContext is a context aware function that returns true if no item in the list fails to meet the predicate.
// If multiple predicate passed, they are treated as logical AND operations.
func AllWithContext[T any](ctx context.Context, items []T, filters ...filtering.ExpressionWithContext[T]) (bool, error) {
filter := filtering.AndWithContext(filters...)
for i, v := range items {
match, err := filter(ctx, i, v)
if err != nil {
return false, fmt.Errorf("error applying filter to index %d: %w", i, err)
}
if !match {
return false, nil
}
}
return true, nil
}
// Any returns true if any item in the slice matches the filter. If multiple predicates are passed,
// they are treated as logical AND operations.
func Any[T any](items []T, filters ...filtering.Expression[T]) bool {
filter := filtering.And(filters...)
for i, v := range items {
if filter(i, v) {
return true
}
}
return false
}
// AnyWithContext is a context aware function that returns true if any item in the slice matches the filter.
func AnyWithContext[T any](ctx context.Context, items []T, filters ...filtering.ExpressionWithContext[T]) (bool, error) {
filter := filtering.AndWithContext(filters...)
for i, v := range items {
match, err := filter(ctx, i, v)
if err != nil {
return false, fmt.Errorf("error applying filter to index %d: %w", i, err)
} else if match {
return true, nil
}
}
return false, nil
}
// Count returns how many items pass the filters
func Count[T any](items []T, filters ...filtering.Expression[T]) int {
if len(filters) == 0 {
return len(items)
}
filter := filtering.And(filters...)
count := 0
for i, v := range items {
if filter(i, v) {
count++
}
}
return count
}
// CountWithContext counts how many items pass the filter
func CountWithContext[T any](ctx context.Context, items []T, filters ...filtering.ExpressionWithContext[T]) (int, error) {
if len(filters) == 0 {
return len(items), nil
}
filter := filtering.AndWithContext(filters...)
count := 0
for i, v := range items {
match, err := filter(ctx, i, v)
if err != nil {
return 0, fmt.Errorf("error applying filter to index %d: %w", i, err)
}
if match {
count++
}
}
return count, nil
}