Blazingly fast Collections package. Inspired by Laravel, written in Go.
go-collections offers a variety of methods and types to be used with slices and maps. Initially, its interface was based on Laravel Collections, but many more methods and functionalities will be added.
This package is still under development, there might be breaking changes introduced. Use with caution!
Pull requests are welcome. See Contributing
There are just functions with a slice type parameter to help the usage of slices. The main disadvantage here is the lack of piping.
func genericFunction() {
Each(
func(_, v int) {
fmt.Println(v) // 2, 3, 4, 5
},
Map(
func(_, v int) int {
fmt.Println(v) // 1, 2, 3, 4
return v + 1
},
[]int{1, 2, 3, 4},
),
)
}
Slice collection is a custom slice type with embedded methods. Most of the available methods here are just calls to the base generic functions, with the advantage of piping calls instead of nesting functions.
func sliceCollection() {
Collect(1, 2, 3, 4).
Map(func(_, v int) int {
fmt.Println(v) // 1, 2, 3, 4
return v + 1
}).
Each(func(_, v int) {
fmt.Println(v) // 2, 3, 4, 5
})
}
The KV collection is a bit more complex. It uses composed of two structs: the map, holding the keys and values, and a slice of keys, used to enable the collection to be ordered in any way needed by the user. This is important due to the lack of ordering on Go maps. The usage is similar to the Slice collection, with the ability to add comparable keys.
func mapCollection() {
CollectMap(map[string]int{"a": 1, "b": 2, "c": 3, "d": 4}).
Sort(collections.Asc[int]()).
Map(func(k string, v int) int {
fmt.Printf("%s: %v\n", k, v) // a: 1, b: 2, c: 3, d: 4
return v + 1
}).
Each(func(k string, v int) {
fmt.Printf("%s: %v\n", k, v) // a: 2, b: 3, c: 4, d: 5
})
}
Before type parameters (aka generics), Go lacked a way to do even trivial collection stuff without cumbersome boilerplate. After 1.18 was released, a myriad of possibilities was open. There are many available options right now, such as the awesome samber/lo. That said, none of the available options were what we (i.e. maintainers of this package) were looking for... So go-collection was born. The aim is to not only offer generic methods to be used with slices and maps but also offer custom types to manage collections in a pipeable fashion.
The major goals for this package are:
- offer a good, clear interface to interact with slices and maps
- use no external dependencies
- good resource usage without micro-optimizations - this is not intended to be used by real-time or performance critical applications
Some of the methods available on the Laravel Collections are - by design - impossible to be implemented in Go. These methods were either adapted to be used in a way that made sense, or ignored completely.
The complete reference of all types and their documentation is listed in their respective godoc. Below is a quick reference for each one of them.
Types
Functions
- Asc
- Average
- AverageE
- Copy
- Cut
- CutE
- Delete
- Desc
- Each
- First
- FirstE
- Get
- GetE
- Last
- LastE
- Map
- Max
- MaxE
- Median
- Min
- MinE
- Pop
- PopE
- Push
- Put
- Search
- SearchE
- Sort
- Sum
Most methods of the slice collection are just calls to the generic functions passing the collection as the slice argument and returning the result to allow piping. In addition, some methods are available:
The numeric collection includes all methods from the generic kv collection and the additional methods listed bellow:
Despite the main description, this is not supposed to be a blazingly fast repository. Rather, it's intended to offer a good interface without deprecating performance. Benchmarks were made comparing the main methods to their respective raw versions using only the native data struct (e.g. slice or map). The full result will always be available as a build artifact of the respective release, but below is some of the main methods compared.
TODO
TODO