Shipped v2 of go-js-array-methods — JS-style Filter, Map, Reduce for Go slices
If you've ever switched between JavaScript and Go in the same week, you've felt this. You're three lines into a Go function, you reach for .filter(), and then you remember: right, for loop. Or write a one-off helper for the third time this month. go-js-array-methods provides Filter, Map, Reduce, Includes, At, Slice, Splice, Push, Pop — 30+ methods named exactly like their JS counterparts. Generics-powered, immutable by default, chainable if you want it. Repo: github.com/bube054/go-js-array-methods 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. The 30+ methods you'd actually reach for: Filter, Map, Reduce (with ReduceRight and *Strict variants that preserve the input type), Find, FindIndex, FindLast, FindLastIndex, Every, Some, Includes, IndexOf, LastIndexOf, At, Slice, Splice, Push, Pop, Shift, Unshift, Concat, Reverse, Fill, CopyWithin, Flat, ForEach, Join, Entries, With, ToString, ValueOf. What's intentionally not in it: Sort — Go's slices.Sort and the sort package already handle this well. Reimplementing them just to match the JS name felt like noise. Keys — for i := range slice is fine. You don't need a library for that one. FlatMap — on the roadmap, just not done yet. Honestly the most likely place a contribution would land cleanly. Immutable by default. Every function returns a new slice. The input never changes, even for "mutating" methods like Push or Splice. JS technically mutates; this doesn't. The trade-off is you don't get aliasing bugs that show up six functions away from where the bug actually is. Negative indexes. At(-1) gives you the last element. Slice(s, -2, -1) works the same as in JS. Out-of-range access returns an error instead of panicking. Map is properly generic. The compiler infers the output type from your callback, so call sites stay 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 to lock the output type to the input type, there's MapStrict. One Go quirk worth flagging. Go doesn't allow type parameters on methods, only on functions. So Array[T].Map() is locked to Array[any] and can't cleanly change the output type. If you want the full type-safe Map, use array.Map as a function directly. The chainable style still works fine for the rest. Sum a slice without writing 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 without leaving 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 examples (runnable, with output) live in array/example_test.go and on pkg.go.dev. A star on the repo helps more than I'd like to admit. It's the cheap signal that tells me which projects to keep working on, and most Go devs don't stumble onto this kind of library on their own — they've usually already given up and written the for loop. If you're in JS-and-Go territory and you know someone who's complained about missing filter/map, sharing this is a real favor to them. That's the audience this is built for. Issues for missing methods or weird edge cases are genuinely valuable. Especially if you can show me the JS behavior you'd expect — that's the spec I'm matching against, and disagreements are usually where the bug is, also PRs are welcome. Repo: github.com/bube054/go-js-array-methods Docs: pkg.go.dev/github.com/bube054/go-js-array-methods/v2 The reference I'm matching: MDN Array.prototype If you build something with it, I'd genuinely like to hear about it. Drop a comment or tag me on GitHub. — @bube054
