DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

Filtering Logic in Go

原文链接

The simplest solution may be to do filtering in-line, looping through your set of records and discarding whatever records don’t match your business requirements

Choosing a filtering library comes at cost though — libraries have to be type-agnostic and thus will generally be using reflect under the hood to do type assertions which is not ideal for performance. 关于filtering库的一个实现思路

1
2
3
4
5
// Filter is a filter function applied to a single record.
type Filter func(string) bool

// FilterBulk is a bulk filter function applied to an entire slice of records.
type FilterBulk func([]string) []string
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
// ApplyFilters applies a set of filters to a record list.
// Each record will be checked against each filter.
// The filters are applied in the order they are passed in.
func ApplyFilters(records []string, filters ...Filter) []string {
// Make sure there are actually filters to be applied.
if len(filters) == 0 {
return records
}

filteredRecords := make([]string, 0, len(records))

// Range over the records and apply all the filters to each record.
// If the record passes all the filters, add it to the final slice.
for _, r := range records {
keep := true

for _, f := range filters {
if !f(r) {
keep = false
break
}
}

if keep {
filteredRecords = append(filteredRecords, r)
}
}

return filteredRecords
}

// ApplyBulkFilters applies a set of filters to the entire slice of records.
// Used when each record filter requires knowledge of the other records, e.g. de-duping.
func ApplyBulkFilters(records []string, filters ...FilterBulk) []string {
for _, f := range filters {
records = f(records)
}

return records
}




var filters = map[int]FilterSet{
1: FilterForAnimals,
2: FilterForIDs,
}


// FilterForAnimals applies a set of filters removing any non-animals.
func FilterForAnimals(records []string) []string {
return ApplyBulkFilters(
ApplyFilters(records,
FilterMagicalCreatures,
FilterStringLength,
FilterInts,
FilterWords,
),
FilterDuplicates,
)
}

// FilterForIDs applies a set of filters removing any non-IDs.
func FilterForIDs(records []string) []string {
return ApplyBulkFilters(
ApplyFilters(records,
FilterIDs,
),
FilterDuplicates,
)
}