Notes: Golang generics with map, filter, and reduce implementation

Search for a command to run...

No comments yet. Be the first to comment.
In this blog we’ll cover retry pattern, what it is, when to use it and when to avoid it with an example. What is the Retry Pattern? The Retry Pattern is a strategy where we retry operations on failure. This is to make sure that business-critical oper...

Idempotency, in practical terms, ensures that repeating the same operation, whether due to retries, user error, or network issues, has no unintended side effects. It guarantees that an operation can be safely retried without causing duplicate changes...

In a distributed system, sharing common resources becomes tricky. We need to ensure that the data we're reading is not stale and that updates happen sequentially during concurrent requests. To avoid such issues, one method to maintain consistency is ...

One of the most common issues I see regularly while reviewing code is database queries that can cause concurrency issues. They look clean and innocent but can cause wrong data during race conditions. In this blog, I’ll try to cover some important bat...

Bloom filters are probabilistic data structures used to test whether an element is possibly in a set or definitely not in a set. These data structures are a neat hack to determine if an element is in a set without actually storing the actual data. A ...

In this blog blog, we’ll see how Go generics can be used to write popular JS array methods.
func Map[T any, R any](slice []T, fn func(T) R) []R {
result := make([]R, len(slice))
for i, v := range slice {
result[i] = fn(v)
}
return result
}
Usage:
numbers := []int{1, 2, 3, 4}
doubled := Map(numbers, func(n int) int { return n * 2 })
fmt.Println(doubled) // [2 4 6 8]
words := []string{"go", "generics"}
lengths := Map(words, func(s string) int { return len(s) })
fmt.Println(lengths) // [2 8]
func Filter[T any](slice []T, fn func(T) bool) []T {
var result []T
for _, v := range slice {
if fn(v) {
result = append(result, v)
}
}
return result
}
Usage:
numbers := []int{1, 2, 3, 4, 5, 6}
evens := Filter(numbers, func(n int) bool { return n%2 == 0 })
fmt.Println(evens) // [2 4 6]
words := []string{"go", "rust", "java", "python"}
shortWords := Filter(words, func(s string) bool { return len(s) <= 4 })
fmt.Println(shortWords) // ["go", "rust", "java"]
func Reduce[T any, R any](slice []T, initial R, fn func(R, T) R) R {
result := initial
for _, v := range slice {
result = fn(result, v)
}
return result
}
Usage:
numbers := []int{1, 2, 3, 4}
sum := Reduce(numbers, 0, func(acc, n int) int { return acc + n })
fmt.Println(sum) // 10
words := []string{"a", "b", "c"}
concat := Reduce(words, "", func(acc, s string) string { return acc + s })
fmt.Println(concat) // "abc"
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
// filter even numbers → double them → sum them
result := Reduce(
Map(
Filter(numbers, func(n int) bool { return n%2 == 0 }),
func(n int) int { return n * 2 },
),
0,
func(acc, n int) int { return acc + n },
)
fmt.Println(result) // 2+4+6+8 → 20 (after doubling: 4+8+12+16 → 40)
You can use these in your code as these make array operations super easy!