Shipped v2 of go-js-array-methods — JS-style Filter, Map, Reduce for Go slices
Source: Dev.to
Quick taste
import "github.com/bube054/go-js-array-methods/v2/array"
nums := []int{1, 2, 3, 4, 5}
even := array.Filter(nums, func(n, _ int, _ []int) bool { return n%2 == 0 })
doubled := array.Map(even, func(n, _ int, _ []int) int { return n * 2 })
// [4, 8]
Or chainable, if you prefer that style:
arr := array.Array[int]{1, 2, 3, 4, 5}
result := arr.
Filter(func(n, _ int, _ []int) bool { return n%2 == 0 }).
Push(6).
Reverse()
// [6, 4, 2]
Both styles are interchangeable. Use whichever fits the surrounding code.
What’s in it
The 30+ methods you’d actually reach for:
Filter,Map,Reduce(withReduceRightand*Strictvariants that preserve the input type)Find,FindIndex,FindLast,FindLastIndexEvery,Some,Includes,IndexOf,LastIndexOfAt,Slice,Splice,Push,Pop,Shift,UnshiftConcat,Reverse,Fill,CopyWithin,Flat,ForEach,JoinEntries,With,ToString,ValueOf
What’s intentionally not in it
- Sort – Go’s
slices.Sortand thesortpackage already handle sorting well. - Keys – Simple
for i := range slicesuffices. - FlatMap – Planned for a future release; contributions are welcome.
A few things worth knowing
Immutable by default. Every function returns a new slice; the input never changes, even for “mutating” methods like Push or Splice. This avoids aliasing bugs.
Negative indexes. At(-1) returns the last element. Slice(s, -2, -1) works like JavaScript. Out‑of‑range access returns an error instead of panicking.
Map is properly generic. The compiler infers the output type from your callback, keeping call sites clean:
nums := []int{1, 2, 3}
strs := array.Map(nums, func(n, _ int, _ []int) string {
return fmt.Sprintf("#%d", n)
})
// []string{"#1", "#2", "#3"} – no type assertions, no []any
If you want the output type locked to the input type, use MapStrict.
Go quirk. Go does not allow type parameters on methods, only on functions. Therefore Array[T].Map() is limited to Array[any]. For a fully type‑safe Map, use the array.Map function directly; the chainable style works for the other methods.
A couple of patterns I find myself using
Sum a slice without a manual accumulator
nums := []int{1, 2, 3, 4}
initial := 0
sum, _ := array.ReduceStrict(nums, func(acc, n, _ int, _ []int) int {
return acc + n
}, &initial)
// sum == 10
Flatten a mixed nested slice
nested := []any{1, []int{2, 3}, []int{4, 5}}
flat, _ := array.Flat[int](nested)
// []int{1, 2, 3, 4, 5}
Transform a slice of strings while preserving type safety
arr := array.Array[string]{"alice", "bob", "carol"}
shouts := arr.MapStrict(func(s string, _ int, _ []string) string {
return strings.ToUpper(s) + "!"
})
// [ALICE! BOB! CAROL!]
More runnable examples with output are available in array/example_test.go and on pkg.go.dev.
If this is useful to you
A star on the repository is a helpful signal that guides which projects I continue to maintain. Most Go developers don’t discover this library on their own and end up writing manual loops.
If you know someone who misses filter/map in Go, sharing this library is a real favor. Issues reporting missing methods or edge cases are valuable—especially when you can point to the expected JavaScript behavior. Pull requests are also welcome.
Links
- Repo:
- Docs:
- Reference: MDN Array.prototype