发布 v2 版 go-js-array-methods — JS 风格的 Filter、Map、Reduce 用于 Go 切片
Source: Dev.to
快速体验
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]
或者链式调用,如果你喜欢这种风格:
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]
两种风格可以互换。使用最适合你代码上下文的方式。
包含哪些方法
30+ 你真正会用到的方法:
Filter,Map,Reduce(以及ReduceRight和*Strict变体,保持输入类型不变)Find,FindIndex,FindLast,FindLastIndexEvery,Some,Includes,IndexOf,LastIndexOfAt,Slice,Splice,Push,Pop,Shift,UnshiftConcat,Reverse,Fill,CopyWithin,Flat,ForEach,JoinEntries,With,ToString,ValueOf
故意未实现的功能
- Sort – Go 的
slices.Sort与sort包已经能够很好地完成排序。 - Keys – 简单的
for i := range slice已足够。 - FlatMap – 计划在未来的版本中实现,欢迎贡献代码。
几件值得了解的事
默认不可变。 每个函数都会返回一个新切片;输入切片永不改变,即使是像 Push 或 Splice 这样的“变异”方法。这可以避免别名导致的 bug。
负索引。 At(-1) 返回最后一个元素。Slice(s, -2, -1) 的行为类似 JavaScript。超出范围的访问会返回错误,而不是 panic。
Map 完全泛型。 编译器会从回调函数中推断输出类型,使调用处保持简洁:
nums := []int{1, 2, 3}
strs := array.Map(nums, func(n, _ int, _ []int) string {
return fmt.Sprintf("#%d", n)
})
// []string{"#1", "#2", "#3"} – 无需类型断言,也不使用 []any
如果希望输出类型锁定为输入类型,请使用 MapStrict。
Go 的怪癖。 Go 不允许在方法上使用类型参数,只能在函数上使用。因此 Array[T].Map() 只能用于 Array[any]。想要完全类型安全的 Map,请直接使用 array.Map 函数;链式风格仍然适用于其他方法。
我常用的几种模式
在不手动声明累加器的情况下求和切片
nums := []int{1, 2, 3, 4}
initial := 0
sum, _ := array.ReduceStrict(nums, func(acc, n, _ int, _ []int) int {
return acc + n
}, &initial)
// sum == 10
将混合嵌套切片扁平化
nested := []any{1, []int{2, 3}, []int{4, 5}}
flat, _ := array.Flat[int](nested)
// []int{1, 2, 3, 4, 5}
在保持类型安全的前提下转换字符串切片
arr := array.Array[string]{"alice", "bob", "carol"}
shouts := arr.MapStrict(func(s string, _ int, _ []string) string {
return strings.ToUpper(s) + "!"
})
// [ALICE! BOB! CAROL!]
更多带有输出的可运行示例请查看 array/example_test.go 与 pkg.go.dev。
如果你觉得有用
在仓库上点个星是一个很好的信号,能帮助我决定继续维护哪些项目。大多数 Go 开发者并不会自行发现这个库,往往会自己写手动循环。
如果你认识的人在 Go 中缺少 filter/map,分享这个库将是一个大帮助。提交缺失方法或边界情况的 Issue 非常有价值——尤其是当你能指明对应的 JavaScript 行为时。也欢迎提交 Pull Request。
链接
- Repo:
- Docs:
- Reference: MDN Array.prototype