在Go语言中,对slice和map是我们最常用的数据结构。比如,计算两个切片的交集、差集;判断切片中的元素是否都满足某个条件的等。我推荐大家使用这个包:elliotchance/pie
。以下是该包的基本情况:
pie 小档案 | |||
---|---|---|---|
star | 1.3 k | used by | -- |
contributors | 22 | 作者 | Elliot Chance |
功能简介 | 该包封装了对切片和map的常用操作,能满足工作中的大部分需求。比如计算切片的交集、差集;对切片中元素按条件过滤的Filter函数;对切片中元素进行数据转换的Each、Map函数等。 同时具有高性能、类型安全的特点。实现中对各函数的参数都做了类型的限制。比如Average函数就只能对整型和浮点型参数有效。 | ||
项目地址 | https://github.com/elliotchance/pie | ||
相关知识 | 切片的底层原理、切片性能 |
pie v2版本需要Go 1.18+。Go1.17及以下版本需要使用v1版本。
go 版本在1.18及以上,会使用pie/v2包,该包使用的是泛型。
package mainimport (
"fmt"
"strings"
"github.com/elliotchance/pie/v2"
)
func main() {
name := pie.Of([]string{"Bob", "Sally", "John", "Jane"}).
FilterNot(func(name string) bool {
return strings.HasPrefix(name, "J")
}).
Map(strings.ToUpper).
Last()
fmt.Println(name) // "SALLY"
}
go1.17及以下版本需要使用pie/v1包。因为在1.17之前go还不支持泛型,所以函数只能针对特定类型的切片。在该v1包中,pie实际上是定义了一组类型切片。比如,代表string切片的pie.Strings类型。代表float64切片的pie.Float64s类型。那么该版本在使用时需要先定义切片的类型。如下:
package mainimport (
"fmt"
"strings"
"github.com/elliotchance/pie/pie"
)
func main() {
var names pie.Strings //看pie的源码Strings的底层类型是[]string
names = []string{"Bob", "Sally", "John", "Jane"}
name := names.FilterNot(func(name string) bool {
return strings.HasPrefix(name, "J")
}).
Map(strings.ToUpper).
Last()
fmt.Println(name) // "SALLY"
}
切片中的元素是否全部或任意一个满足指定的条件。
对切片元素进行排序功能。
对切片中的元素去重。
对切片进行前、后截取。
两个或多个切片之间的集合运算
切片元素进行算数运算功能(只针对Integer和float类型的切片有效)。
对切片中的元素进行数据转换功能:Each、Map、Filter、Flat、Reducer
针对map的操作:
更多、更详细的功能请参考pie包的源码。
pie包几乎把slice经常用到的功能都做了封装,可谓是给开发者节省了大量时间。同时,v2包利用了泛型中的类型限制,保证了类型的安全。在性能方面,该包采用了很多策略:在已知切片长度的情况下尽可能给slice分配固定长度的内存,减少在使用append时内存申请的次数;使用切片截取的形式,避免内存再次分配。
推荐阅读