No description
- Go 100%
| cmd | ||
| .gitignore | ||
| cache.go | ||
| filter.go | ||
| filter_test.go | ||
| helper.go | ||
| LICENSE | ||
| README.md | ||
filter - a simple struct field filter and sorter for go
Query Syntax
Matching
Explicit match: <struct field>:<struct value>
Wildcard match (use ** to match the '*' character):
<struct field>:*<right part of struct value>
<struct field>:<left part of struct value>*
<struct field>:*<middl of struct value>*
Nested structs: <struct field>.<struct field>:<struct value>
Multiple matches (seperated by a single whitespace):
<struct field>:<struct value> <struct field>:<struct value>*
Bool does not support the wildcard operator, only the literal strings true and false.
Sorting
The sort statement consists of the literal string sort, the field name (nesting like above is supported) and the literal strings asc or desc.
sort:<struct field>:asc
sort:<struct field>:desc
sort:<struct field>.<struct field>:desc
Struct fields
Supported struct field values are:
int,int8,int16,int32,int64float32,float64stringbool
For nested structs:
struct
Filter logic
Supported logical matching:
AND- all statements have to match (if no logic is provided, this is the default)OR- only one statement has to matchNOT- none of the statements have to match
Examples
// Example data structure
type Example struct {
String string
Int int
Bool bool
Struct Struct1
}
type Struct1 struct {
String string
Struct Struct2
}
type Struct2 struct {
Int int
}
// Filter implements the filter.Filter interface
type Filter []Example
func (v Filter) Len() int { return len(v) }
func (v Filter) Index(i int) interface{} { return v[i] }
func (v *Filter) Remove(i, j int) { *v = append((*v)[:i], (*v)[j:]...) }
// Example data
var data = Filter{
{"str1", 42, true, Struct1{"s1", Struct2{1}}},
{"2str", 42, true, Struct1{"s2", Struct2{2}}},
{"str3", 42, false, Struct1{"s3", Struct2{3}}},
}
Explicit match
filter.NewQuery("OR Bool:true").Filter(&data)
data = [{str1 42 true {s1 {1}}} {str2 42 true {s2 {2}}}]
Wildcard match
Wildcard operator: *
To match the '*' character use: **
filter.NewQuery("OR String:s*").Filter(&data)
data = [{str1 42 true {s1 {1}}} {str3 42 false {s3 {3}}}]
Nested struct match
filter.NewQuery("OR Struct.Struct.Int:3").Filter(&data)
data = [{str3 42 false {s3 {3}}}]
Multiple matches
filter.NewQuery("Struct.String:*2 Bool:true").Filter(&data)
data = [{2str 42 true {s2 {2}}}]
Sorting
The GenericFilter does not support sorting.
Sort
filter.NewQuery("sort:Bool:desc").Filter(&data)
data = [{str1 42 false {s1 {1}}} {2str 42 true {s2 {2}}} {str3 42 true {s3 {3}}}]
Sort and Filter
filter.NewQuery("sort:Bool:desc String:str*").Filter(&data)
data = [{str1 42 false {s1 {1}}} {str3 42 true {s3 {3}}}]
Benchmarks
go test -bench .
BenchmarkNewQuerySimple-4 2000000 974 ns/op 272 B/op 8 allocs/op
BenchmarkNewQueryComplex-4 500000 2779 ns/op 848 B/op 20 allocs/op
BenchmarkNewQueryComplexOr-4 500000 2677 ns/op 832 B/op 20 allocs/op
BenchmarkNewQuerySort-4 3000000 576 ns/op 160 B/op 4 allocs/op
BenchmarkNewQuerySortSimple-4 1000000 1192 ns/op 304 B/op 9 allocs/op
BenchmarkNewQuerySortComplex-4 500000 2598 ns/op 784 B/op 19 allocs/op
BenchmarkNewQuerySortComplexOr-4 500000 2326 ns/op 768 B/op 19 allocs/op
BenchmarkFilterSimple-4 1000000 2123 ns/op 432 B/op 12 allocs/op
BenchmarkFilterComplex-4 200000 6840 ns/op 672 B/op 42 allocs/op
BenchmarkFilterComplexOr-4 300000 5929 ns/op 744 B/op 30 allocs/op
BenchmarkSort-4 200000 7859 ns/op 1864 B/op 51 allocs/op
BenchmarkSortFilterSimple-4 200000 6294 ns/op 1432 B/op 39 allocs/op
BenchmarkSortFilterComplex-4 200000 11990 ns/op 1672 B/op 69 allocs/op
BenchmarkSortFilterComplexOr-4 200000 12138 ns/op 2176 B/op 69 allocs/op
BenchmarkGenericFilterSimple-4 300000 5939 ns/op 1200 B/op 24 allocs/op
BenchmarkGenericFilterComplex-4 100000 16638 ns/op 1680 B/op 84 allocs/op
BenchmarkGenericFilterComplexOr-4 200000 11846 ns/op 2360 B/op 49 allocs/op