Reputation: 311
I have an array of structs (struct detailed at bottom)
I want to find all the structs that match certain values for, example, leg and site.
So if leg=101 and site=1024A give back all the structs that match these criteria.
What is the Go manner for doing this?
type JanusDepth struct {
dataset string
ob string
leg string
site string
hole string
age float64
depth float64
long float64
lat float64
}
Upvotes: 6
Views: 7368
Reputation: 29
More than 10 years later, I'm wondering why I can't find anything better than a manual for loop in order to filter some data from a list. I've came to create custom helper functions for this, as follows:
// Filter the slice based on the predicate and return the result
func filter[S ~[]T, T any](slice S, predicate func(T) bool) []T {
out := make([]T, 0)
for _, item := range slice {
if predicate(item) {
out = append(out, item)
}
}
return out
}
// For cases where you have to filter the slice and also keep the items that do not match the predicate
func filterOr[S ~[]T, T any](slice S, predicate func(T) bool) ([]T, []T) {
out := make([]T, 0)
orOut := make([]T, 0)
for _, item := range slice {
if predicate(item) {
out = append(out, item)
} else {
orOut = append(orOut, item)
}
}
return out, orOut
}
They can then be used like this:
package main
import "fmt"
func isEven(num int) bool { return num%2 == 0 }
func main() {
initialSlice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
evenNumbers1 := filter(initialSlice, isEven)
// Even numbers: [2 4 6 8 10]
fmt.Printf("Even numbers: %v\n", evenNumbers1)
evenNumbers2, oddNumbers := filterOr(initialSlice, isEven)
// Even numbers: [2 4 6 8 10]
fmt.Printf("Even numbers: %v\n", evenNumbers2)
// Odd numbers: [1 3 5 7 9]
fmt.Printf("Odd numbers: %v\n", oddNumbers)
}
Thanks to this, my code is a little less bloated.
Upvotes: 0
Reputation: 1471
If your data is ordered on one key, then you can use http://golang.org/pkg/sort/#Search to do a binary search, which is better for performance if the amount of data is moderate to large.
Upvotes: 2
Reputation: 24818
Dead simple:
leg := "101"
site := "1024A"
filtered := []JanusDepth{}
for _, e := range MyArrayOfStructs {
if(e.leg == leg && e.site == site) {
filtered = append(filtered, e)
}
}
// filtered contains your elements
Upvotes: 10