Documentation
¶
Overview ¶
Package filter provides generic filtering utilities for maps and slices with various logical operations.
The package is designed to make filtering operations on collections more concise and readable by providing a set of utility functions that can be combined to create complex filtering logic.
Key features:
- Filter maps and slices with simple predicates - Combine multiple filters with logical operations (AND, OR, NOT AND, NOT OR) - Select elements from slices (first, last, random) - Convert slices to filter functions - Type-safe operations using Go generics
Example usage for filtering slices:
numbers := []int{1, 2, 3, 4, 5}
// Filter even numbers
isEven := func(n int) bool {
return n%2 == 0
}
evenNumbers := filter.FilterSlice(numbers, isEven)
// evenNumbers = [2, 4]
Example usage for filtering maps:
users := map[string]int{
"Alice": 25,
"Bob": 30,
"Carol": 22,
"Dave": 35,
}
// Filter users older than 25
isOlderThan25 := func(age int) bool {
return age > 25
}
olderUsers := filter.FilterMap(users, isOlderThan25)
// olderUsers = map[Bob:30 Dave:35]
For more examples and detailed documentation, see the README.md file.
Example (CombiningFilters) ¶
package main
import (
"fmt"
"github.com/dioad/filter"
)
func main() {
// Creating reusable filters
isEven := func(n int) bool { return n%2 == 0 }
isPositive := func(n int) bool { return n > 0 }
isGreaterThan10 := func(n int) bool { return n > 10 }
// Combining filters with logical operations
isEvenAndPositive := filter.And(isEven, isPositive)
isEvenOrGreaterThan10 := filter.Or(isEven, isGreaterThan10)
isNotEvenAndNotPositive := filter.NotAnd(isEven, isPositive)
numbers := []int{-4, -3, -2, -1, 0, 1, 2, 3, 4, 11, 12}
// Apply the combined filters
evenAndPositive := filter.FilterSlice(numbers, isEvenAndPositive)
evenOrGreaterThan10 := filter.FilterSlice(numbers, isEvenOrGreaterThan10)
notEvenAndNotPositive := filter.FilterSlice(numbers, isNotEvenAndNotPositive)
fmt.Println("Even and positive:", evenAndPositive)
fmt.Println("Even or greater than 10:", evenOrGreaterThan10)
fmt.Println("Not (even and positive):", notEvenAndNotPositive)
}
Output: Even and positive: [2 4 12] Even or greater than 10: [-4 -2 0 2 4 11 12] Not (even and positive): [-4 -3 -2 -1 0 1 3 11]
Example (ConvertingSlicesToFilters) ¶
package main
import (
"fmt"
"github.com/dioad/filter"
)
func main() {
// Define a list of allowed values
allowedIDs := []int{1, 3, 5}
// Convert the slice to a filter function
hasAllowedID := filter.SliceToOrFilter(allowedIDs, func(id int) func(int) bool {
return filter.Equals(id)
})
// Apply the filter to a list of IDs
allIDs := []int{1, 2, 3, 4, 5, 6}
filteredIDs := filter.FilterSlice(allIDs, hasAllowedID)
fmt.Println("Allowed IDs:", filteredIDs)
}
Output: Allowed IDs: [1 3 5]
Example (FilteringMaps) ¶
package main
import (
"fmt"
"github.com/dioad/filter"
)
func main() {
// Map filtering
users := map[string]int{
"Alice": 25,
"Bob": 30,
"Carol": 22,
"Dave": 35,
}
// Filter users older than 25
isOlderThan25 := func(age int) bool {
return age > 25
}
olderUsers := filter.FilterMap(users, isOlderThan25)
fmt.Println("Users older than 25:", olderUsers)
// Filter users younger than 30 and older than 20
isYoungerThan30 := func(age int) bool {
return age < 30
}
isOlderThan20 := func(age int) bool {
return age > 20
}
middleAgedUsers := filter.FilterMapAnd(users, isYoungerThan30, isOlderThan20)
fmt.Println("Users between 20 and 30:", middleAgedUsers)
}
Output: Users older than 25: map[Bob:30 Dave:35] Users between 20 and 30: map[Alice:25 Carol:22]
Example (FilteringSlices) ¶
package main
import (
"fmt"
"github.com/dioad/filter"
)
func main() {
// Basic filtering
numbers := []int{1, 2, 3, 4, 5}
// Filter even numbers
isEven := func(n int) bool {
return n%2 == 0
}
evenNumbers := filter.FilterSlice(numbers, isEven)
fmt.Println("Even numbers:", evenNumbers)
// Combining filters with AND
isGreaterThanThree := func(n int) bool {
return n > 3
}
evenAndGreaterThanThree := filter.FilterSliceAnd(numbers, isEven, isGreaterThanThree)
fmt.Println("Even and greater than 3:", evenAndGreaterThanThree)
// Combining filters with OR
isLessThanTwo := func(n int) bool {
return n < 2
}
evenOrLessThanTwo := filter.FilterSliceOr(numbers, isEven, isLessThanTwo)
fmt.Println("Even or less than 2:", evenOrLessThanTwo)
}
Output: Even numbers: [2 4] Even and greater than 3: [4] Even or less than 2: [1 2 4]
Example (SelectingFromSlices) ¶
package main
import (
"fmt"
"github.com/dioad/filter"
)
func main() {
fruits := []string{"apple", "banana", "cherry", "date"}
// Select first element
first := filter.SliceSelectFirst(fruits)
fmt.Println("First fruit:", *first)
// Select last element
last := filter.SliceSelectLast(fruits)
fmt.Println("Last fruit:", *last)
// Select a specific element using filtering
cherries := filter.FilterSlice(fruits, filter.Equals("cherry"))
cherry, err := filter.OneOnly(cherries)
if err == nil {
fmt.Println("Found cherry:", *cherry)
}
}
Output: First fruit: apple Last fruit: date Found cherry: cherry
Index ¶
- Variables
- func And[T any](filters ...func(T) bool) func(T) bool
- func Equals[T comparable](v T) func(T) bool
- func FilterMap[K comparable, V any](m map[K]V, filter func(V) bool) map[K]V
- func FilterMapAnd[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
- func FilterMapNotAnd[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
- func FilterMapNotOr[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
- func FilterMapOr[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
- func FilterSlice[T any](l []T, filter func(T) bool) []T
- func FilterSliceAnd[T any](l []T, filters ...func(T) bool) []T
- func FilterSliceNotAnd[T any](l []T, filters ...func(T) bool) []T
- func FilterSliceNotOr[T any](l []T, filters ...func(T) bool) []T
- func FilterSliceOr[T any](l []T, filters ...func(T) bool) []T
- func NotAnd[T any](filters ...func(T) bool) func(T) bool
- func NotOr[T any](filters ...func(T) bool) func(T) bool
- func OneOnly[T any](l []T) (*T, error)
- func Or[T any](filters ...func(T) bool) func(T) bool
- func SliceSelectFirst[T any](l []T) *T
- func SliceSelectLast[T any](l []T) *T
- func SliceSelectRandom[T any](l []T) *T
- func SliceSelectRandomWithGenerator[T any](l []T, generator func(int) int) *T
- func SliceToAndFilter[T any, U any](list []T, filterFunc func(T) func(U) bool) func(U) bool
- func SliceToOrFilter[T any, U any](list []T, filterFunc func(T) func(U) bool) func(U) bool
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNoElement is returned when an operation expects at least one element but the slice is empty ErrNoElement = errors.New("no element") // ErrTooManyElements is returned when an operation expects exactly one element but the slice has more ErrTooManyElements = errors.New("too many elements") )
Functions ¶
func And ¶ added in v0.5.0
And creates a filter function that combines multiple filters with logical AND. The returned filter returns true only if all the provided filters return true for a given value.
Example:
isEven := func(n int) bool { return n%2 == 0 }
isPositive := func(n int) bool { return n > 0 }
isEvenAndPositive := filter.And(isEven, isPositive)
// isEvenAndPositive(4) returns true
// isEvenAndPositive(-2) returns false
func Equals ¶
func Equals[T comparable](v T) func(T) bool
Equals creates a filter function that checks if a value equals the provided value. This is a basic building block for creating more complex filters.
Example:
isThree := filter.Equals(3) // isThree(3) returns true // isThree(4) returns false
func FilterMap ¶
func FilterMap[K comparable, V any](m map[K]V, filter func(V) bool) map[K]V
FilterMap filters a map using a single filter function. A key-value pair is included in the result only if the filter returns true for the value.
Parameters:
- m: The input map to filter
- filter: A function that takes a value and returns a boolean
Returns:
- A new map containing only the key-value pairs where the value passed the filter
Example:
users := map[string]int{
"alice": 25,
"bob": 30,
"carol": 22,
}
isOver25 := func(age int) bool { return age > 25 }
result := filter.FilterMap(users, isOver25)
// result = map[bob:30]
func FilterMapAnd ¶
func FilterMapAnd[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
FilterMapAnd filters a map using multiple filter functions combined with logical AND. A key-value pair is included in the result only if all filters return true for the value.
Parameters:
- m: The input map to filter
- filters: A variadic list of filter functions
Returns:
- A new map containing only the key-value pairs where the value passed all filters
Example:
users := map[string]User{
"alice": {Age: 25, Role: "Admin"},
"bob": {Age: 30, Role: "User"},
"carol": {Age: 22, Role: "Admin"},
}
isAdmin := func(u User) bool { return u.Role == "Admin" }
isOver25 := func(u User) bool { return u.Age > 25 }
result := filter.FilterMapAnd(users, isAdmin, isOver25)
// result contains only "alice"
func FilterMapNotAnd ¶
func FilterMapNotAnd[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
FilterMapNotAnd filters a map using multiple filter functions combined with logical NOT AND. A key-value pair is included in the result if any of the filters return false for the value.
Parameters:
- m: The input map to filter
- filters: A variadic list of filter functions
Returns:
- A new map containing the key-value pairs where the value failed at least one filter
Example:
users := map[string]User{
"alice": {Age: 25, Role: "Admin"},
"bob": {Age: 30, Role: "User"},
"carol": {Age: 22, Role: "Admin"},
}
isAdmin := func(u User) bool { return u.Role == "Admin" }
isOver25 := func(u User) bool { return u.Age > 25 }
result := filter.FilterMapNotAnd(users, isAdmin, isOver25)
// result contains "bob" and "carol" (either not admin or not over 25)
func FilterMapNotOr ¶
func FilterMapNotOr[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
FilterMapNotOr filters a map using multiple filter functions combined with logical NOT OR. A key-value pair is included in the result only if all filters return false for the value.
Parameters:
- m: The input map to filter
- filters: A variadic list of filter functions
Returns:
- A new map containing only the key-value pairs where the value failed all filters
Example:
users := map[string]User{
"alice": {Age: 25, Role: "Admin"},
"bob": {Age: 30, Role: "User"},
"carol": {Age: 22, Role: "Admin"},
}
isAdmin := func(u User) bool { return u.Role == "Admin" }
isOver25 := func(u User) bool { return u.Age > 25 }
result := filter.FilterMapNotOr(users, isAdmin, isOver25)
// result contains only "bob" (not admin and not over 25)
func FilterMapOr ¶
func FilterMapOr[K comparable, V any](m map[K]V, filters ...func(V) bool) map[K]V
FilterMapOr filters a map using multiple filter functions combined with logical OR. A key-value pair is included in the result if any of the filters return true for the value.
Parameters:
- m: The input map to filter
- filters: A variadic list of filter functions
Returns:
- A new map containing the key-value pairs where the value passed at least one filter
Example:
users := map[string]User{
"alice": {Age: 25, Role: "Admin"},
"bob": {Age: 30, Role: "User"},
"carol": {Age: 22, Role: "Admin"},
}
isAdmin := func(u User) bool { return u.Role == "Admin" }
isOver25 := func(u User) bool { return u.Age > 25 }
result := filter.FilterMapOr(users, isAdmin, isOver25)
// result contains "alice", "bob", and "carol"
func FilterSlice ¶
FilterSlice filters a slice using a single filter function. An element is included in the result only if the filter returns true for it.
Parameters:
- l: The input slice to filter
- filter: A function that takes an element and returns a boolean
Returns:
- A new slice containing only the elements that passed the filter
Example:
numbers := []int{1, 2, 3, 4, 5}
isEven := func(n int) bool { return n%2 == 0 }
result := filter.FilterSlice(numbers, isEven)
// result = [2, 4]
func FilterSliceAnd ¶
FilterSliceAnd filters a slice using multiple filter functions combined with logical AND. An element is included in the result only if all filters return true for it.
Parameters:
- l: The input slice to filter
- filters: A variadic list of filter functions
Returns:
- A new slice containing only the elements that passed all filters
Example:
numbers := []int{1, 2, 3, 4, 5}
isEven := func(n int) bool { return n%2 == 0 }
isGreaterThanThree := func(n int) bool { return n > 3 }
result := filter.FilterSliceAnd(numbers, isEven, isGreaterThanThree)
// result = [4]
func FilterSliceNotAnd ¶
FilterSliceNotAnd filters a slice using multiple filter functions combined with logical NOT AND. An element is included in the result if any of the filters return false for it.
Parameters:
- l: The input slice to filter
- filters: A variadic list of filter functions
Returns:
- A new slice containing the elements for which at least one filter returned false
func FilterSliceNotOr ¶
FilterSliceNotOr filters a slice using multiple filter functions combined with logical NOT OR. An element is included in the result only if all filters return false for it.
Parameters:
- l: The input slice to filter
- filters: A variadic list of filter functions
Returns:
- A new slice containing only the elements for which all filters returned false
func FilterSliceOr ¶
FilterSliceOr filters a slice using multiple filter functions combined with logical OR. An element is included in the result if any of the filters return true for it.
Parameters:
- l: The input slice to filter
- filters: A variadic list of filter functions
Returns:
- A new slice containing the elements that passed at least one filter
Example:
numbers := []int{1, 2, 3, 4, 5}
isEven := func(n int) bool { return n%2 == 0 }
isLessThanTwo := func(n int) bool { return n < 2 }
result := filter.FilterSliceOr(numbers, isEven, isLessThanTwo)
// result = [1, 2, 4]
func NotAnd ¶ added in v0.5.0
NotAnd creates a filter function that combines multiple filters with logical NOT AND. The returned filter returns true only if at least one of the provided filters returns false for a given value.
Example:
isEven := func(n int) bool { return n%2 == 0 }
isPositive := func(n int) bool { return n > 0 }
isNotEvenOrNotPositive := filter.NotAnd(isEven, isPositive)
// isNotEvenOrNotPositive(4) returns false
// isNotEvenOrNotPositive(-2) returns true
// isNotEvenOrNotPositive(3) returns true
func NotOr ¶ added in v0.5.0
NotOr creates a filter function that combines multiple filters with logical NOT OR. The returned filter returns true only if all of the provided filters return false for a given value.
Example:
isEven := func(n int) bool { return n%2 == 0 }
isNegative := func(n int) bool { return n < 0 }
isNotEvenAndNotNegative := filter.NotOr(isEven, isNegative)
// isNotEvenAndNotNegative(4) returns false
// isNotEvenAndNotNegative(-3) returns false
// isNotEvenAndNotNegative(3) returns true
func OneOnly ¶
OneOnly returns the only element in a slice, or an error if the slice doesn't contain exactly one element.
Parameters:
- l: The input slice
Returns:
- A pointer to the only element in the slice, or nil if an error occurred
- An error: ErrNoElement if the slice is empty, ErrTooManyElements if it has more than one element
Example:
numbers := []int{42}
result, err := filter.OneOnly(numbers)
// result points to 42, err is nil
func Or ¶ added in v0.5.0
Or creates a filter function that combines multiple filters with logical OR. The returned filter returns true if any of the provided filters return true for a given value.
Example:
isEven := func(n int) bool { return n%2 == 0 }
isNegative := func(n int) bool { return n < 0 }
isEvenOrNegative := filter.Or(isEven, isNegative)
// isEvenOrNegative(4) returns true
// isEvenOrNegative(-3) returns true
// isEvenOrNegative(3) returns false
func SliceSelectFirst ¶
func SliceSelectFirst[T any](l []T) *T
SliceSelectFirst returns a pointer to the first element in a slice. This is useful when you need to access the first element without modifying the original slice.
Parameters:
- l: The input slice
Returns:
- A pointer to the first element, or nil if the slice is empty
Example:
items := []string{"apple", "banana", "cherry"}
first := filter.SliceSelectFirst(items)
// *first = "apple"
func SliceSelectLast ¶
func SliceSelectLast[T any](l []T) *T
SliceSelectLast returns a pointer to the last element in a slice. This is useful when you need to access the last element without modifying the original slice.
Parameters:
- l: The input slice
Returns:
- A pointer to the last element, or nil if the slice is empty
Example:
items := []string{"apple", "banana", "cherry"}
last := filter.SliceSelectLast(items)
// *last = "cherry"
func SliceSelectRandom ¶
func SliceSelectRandom[T any](l []T) *T
SliceSelectRandom returns a pointer to a random element in a slice. This function uses the default random number generator.
Note: This function is not cryptographically secure and should not be used for security-sensitive applications.
Parameters:
- l: The input slice
Returns:
- A pointer to a randomly selected element, or nil if the slice is empty
Example:
items := []string{"apple", "banana", "cherry"}
random := filter.SliceSelectRandom(items)
// *random = one of "apple", "banana", or "cherry"
func SliceSelectRandomWithGenerator ¶
SliceSelectRandomWithGenerator returns a pointer to a random element in a slice using a custom random number generator. This allows for deterministic random selection, which can be useful for testing.
Parameters:
- l: The input slice
- generator: A function that takes the length of the slice and returns a random index
Returns:
- A pointer to a randomly selected element, or nil if the slice is empty or if generator is nil
Example:
items := []string{"apple", "banana", "cherry"}
// Always select the first element for testing
alwaysFirst := func(n int) int { return 0 }
result := filter.SliceSelectRandomWithGenerator(items, alwaysFirst)
// *result = "apple"
func SliceToAndFilter ¶
SliceToAndFilter converts a slice of values into a single filter function using logical AND. The returned filter function returns true only if all of the individual filters (created from the slice elements) return true.
Parameters:
- list: A slice of values to convert into filters
- filterFunc: A function that converts each value in the list to a filter function
Returns:
- A filter function that combines all the individual filters with logical AND
Example:
requiredTags := []string{"important", "urgent"}
hasAllRequiredTags := filter.SliceToAndFilter(requiredTags, func(tag string) func(task Task) bool {
return func(task Task) bool { return task.HasTag(tag) }
})
// hasAllRequiredTags returns true only for tasks that have both "important" and "urgent" tags
func SliceToOrFilter ¶
SliceToOrFilter converts a slice of values into a single filter function using logical OR. The returned filter function returns true if any of the individual filters (created from the slice elements) return true.
Parameters:
- list: A slice of values to convert into filters
- filterFunc: A function that converts each value in the list to a filter function
Returns:
- A filter function that combines all the individual filters with logical OR
Example:
allowedIDs := []int{1, 3, 5}
hasAllowedID := filter.SliceToOrFilter(allowedIDs, func(id int) func(user User) bool {
return func(user User) bool { return user.ID == id }
})
// hasAllowedID returns true for users with ID 1, 3, or 5
Types ¶
This section is empty.