Created
December 1, 2020 10:07
-
-
Save rstropek/f33175e35feaa4d44a240947a5b01226 to your computer and use it in GitHub Desktop.
Generic iterator in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"strings" | |
) | |
// Generic iterator function type | |
type iteratorFunc[T any] func() *T; | |
// Generic function for iteration | |
func next[T any](iterator iteratorFunc[T]) *T { return iterator() } | |
// Generic function executing a given function for each item in iterator | |
func forEach[T any](iterator iteratorFunc[T], body func(T)) { | |
for ptr := next(iterator); ptr != nil; ptr = next(iterator) { | |
body(*ptr) | |
} | |
} | |
// Generic predicate | |
type predicate[T any] func(item T) bool; | |
// Generic function filtering based on a given predicate | |
func filter[T any](iterator iteratorFunc[T], predicate func(T) bool) iteratorFunc[T] { | |
return func() *T { | |
var item *T | |
for item = next(iterator); item != nil && !predicate(*item); item = next(iterator) { } | |
return item | |
} | |
} | |
// Generic function that generates an iterator from a given slice | |
func iteratorFromSlice[T any](items []T) iteratorFunc[T] { | |
return func() *T { | |
if len(items) < 1 { | |
return nil | |
} | |
firstItem := &items[0] | |
items = items[1:] | |
return firstItem | |
} | |
} | |
type user struct { | |
name string | |
age int | |
} | |
func main() { | |
users := []user{ | |
user{name: "Foo", age: 42}, | |
user{name: "Bar", age: 43}, | |
user{name: "FooBar", age: 44}, | |
} | |
forEach( | |
filter( | |
iteratorFromSlice(users), | |
func(u user) bool { return strings.HasPrefix(u.name, "Foo"); }), | |
func(u user) { fmt.Printf("User is %s\n", u.name) }) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment