English | 简体中文
go-collection provides developers with a convenient set of functions for working with common slices, maps, and arrays data. These functions are based on the generic types of Go 1.18, which makes it easier to use them without annoying type assertions. In addition to using these functions directly, it also supports method chaining.
collect.Reduce(collect.Filter(collect.Map([]int{1, 2, 3}, fn), fn), fn)Equivalent to:
collect.UseSlice([]int{1, 2, 3}).Map(fn).Filter(fn).Reduce(fn)go get -u github.com/sxyazi/go-collectionThen import it
import collect "github.com/sxyazi/go-collection"Its API is very simple and if you have used other similar packages, you should be able to get started with it in a few minutes. For convenience, they are described below in function form.
The corresponding chained function is collect.UseSlice()
-
Lengets the length of the sliceExamples
d1 := []int{1, 2, 3} collect.Len(d1) // 3 d2 := []string{"a", "b", "c"} collect.Len(d2) // 3
-
Eachiterates over each element in the sliceExamples
d := []float64{1, 2, 3} collect.Each(d, func(value float64, index int) { fmt.Println(index, value) })
-
Emptychecks if the slice is emptyExamples
var d []int collect.Empty(d) // true
-
Samechecks if the contents of two slices are the sameExamples
d1 := []int{1, 2, 3} d2 := []int{1, 2, 3} collect.Same(d1, d2) // true d3 := [][]int{{1, 2, 3}, {4, 5, 6}} d4 := [][]int{{1, 2, 3}, {4, 5, 6}} collect.Same(d3, d4) // true
-
Firstgets the first element of the sliceExamples
d1 := []int{1, 2, 3} value, ok := collect.First(d1) // 1, true var d2 []int value, ok = collect.First(d2) // 0, false
-
Lastgets the last element of the sliceExamples
d1 := []int{1, 2, 3} value, ok := collect.Last(d1) // 3, true var d2 []int value, ok = collect.Last(d2) // 0, false
-
Indexgets the index of the specified element in the slice, and returns -1 if it does not exist.Examples
d1 := []int{1, 2, 3} collect.Index(d1, 2) // 1 s1 := []string{"a", "b", "c"} s2 := []string{"d", "e", "f"} collect.Index([][]string{s1, s2}, s2) // 1
-
Containschecks if the slice contains the specified elementExamples
d1 := []int{1, 2, 3} collect.Contains(d1, 2) // true s1 := []string{"a", "b", "c"} s2 := []string{"d", "e", "f"} collect.Contains([][]string{s1, s2}, s2) // true
-
Diffcomputes the difference set of two slicesExamples
d := []int{1, 2, 3} collect.Diff(d, []int{2, 3}) // []int{1}
-
Filterfilters the elements in the sliceExamples
collect.Filter([]int{1, 2, 3, 4, 5}, func(value, index int) bool { return value % 2 == 0 }) // []int{2, 4}
-
Mapiterates over and sets the value of the elements in the sliceExamples
collect.Map([]int{1, 2, 3}, func(value, index int) int { return value * 2 }) // []int{2, 4, 6}
-
Uniqueremoves duplicate elements in the sliceExamples
d := []int{1, 2, 3, 3, 4} collect.Unique(d) // []int{1, 2, 3, 4}
-
Duplicatesgets the duplicate elements in the sliceExamples
d := []string{"a", "b", "a", "c"} collect.Duplicates(d) // map[int]string{2: "a"}
-
Mergemerges the current slice with other slicesExamples
d1 := []int{1, 2} d2 := []int{3, 4} d3 := []int{5, 6} collect.Merge(d1, d2) // []int{1, 2, 3, 4} collect.Merge(d1, d2, d3) // []int{1, 2, 3, 4, 5, 6}
-
Randomgets an element of the slice at randomExamples
d := []int{1, 2} value, ok := collect.Random(d) // 1 or 2, true d := []int{} value, ok := collect.Random(d) // 0, false
-
Reversereverses the elements in a sliceExamples
d := []int{1, 2} collect.Reverse(d) // []int{2, 1}
-
Shufflerandomly shuffles the elements in a sliceExamples
d := []int{1, 2} collect.Shuffle(d) // []int{1, 2} or []int{2, 1}
-
Slicetakes a segment from a sliceExamples
Function signature:
Slice(items T, offset int)d := []int{1, 2, 3, 4, 5} collect.Slice(d, 2) // []int{3, 4, 5} collect.Slice(d, -1) // []int{5} collect.Slice(d, -2) // []int{4, 5}
Function signature:
Slice(items T, offset, length int)d := []int{1, 2, 3, 4, 5} collect.Slice(d, 0, 2) // []int{1, 2} collect.Slice(d, 2, 3) // []int{3, 4, 5} collect.Slice(d, 3, -2) // []int{3, 4} collect.Slice(d, -4, 3) // []int{2, 3, 4}
-
Splitsplits a slice into multiple slices by the specified amountExamples
d := []int{1, 2, 3, 4, 5} collect.Split(d, 2) // [][]int{{1, 2}, {3, 4}, {5}}
-
Spliceremoves a segment from the sliceExamples
Function signature:
Splice(items T, offset int)d := []int{1, 2, 3, 4, 5} collect.Splice(&d, 2) // []int{3, 4, 5} d // []int{1, 2}
Function signature:
Splice(items T, offset, length int)d := []int{1, 2, 3, 4, 5} collect.Splice(&d, 2, 2) // []int{3, 4} d // []int{1, 2, 5}
Function signature:
Splice(items T, offset, length int, replacements ...T|E)d1 := []int{1, 2, 3, 4} collect.Splice(&d1, 1, 2, []int{22, 33}) // []int{2, 3} d1 // []int{1, 22, 33, 4} d2 := []int{1, 2, 3, 4} collect.Splice(&d2, 1, 2, 22, 33) // []int{2, 3} d2 // []int{1, 22, 33, 4} d3 := []int{1, 2, 3, 4} collect.Splice(&d3, 1, 2, []int{22}, 33, []int{55}) // []int{2, 3} d3 // []int{1, 22, 33, 55, 4}
It is worth noting that this method also supports the use of negative numbers as arguments, and its behavior is the same as that of
Slice, which is not repeated here due to space constraints. -
Reducereduces the collection to a single value, and the parameters of each iteration are the results of the previous iterationExamples
collect.Reduce([]int{1, 2, 3}, 100, func(carry, value, key int) int { return carry + value }) // 106
-
Popremoves and returns the last element of the collectionExamples
d := []int{1, 2} v, ok := collect.Pop(&d) // 2, true d // []int{1} c := collect.UseSlice([]int{1, 2}) v, ok := c.Pop() // 2, true c.All() // []int{1}
-
Pushappends an element to the end of a collectionExamples
d := []int{1, 2} Push(&d, 3) d // []int{1, 2, 3} collect.UseSlice([]int{1, 2}).Push(3).All() // []int{1, 2, 3}
-
Wherefilters the collection by the specified rulesExamples
Function signature:
Where(items T, target any)collect.Where([]int{1, 2, 3}, 2) // []int{2}
Function signature:
Where(items T, operator string, target any)d := []int{1, 2, 3, 4} collect.Where(d, "=", 2) // []int{2} collect.Where(d, "!=", 2) // []int{1, 3, 4} collect.Where(d, ">", 2) // []int{3, 4} collect.Where(d, ">=", 2) // []int{2, 3, 4} collect.Where(d, "<", 3) // []int{1, 2} collect.Where(d, "<=", 3) // []int{1, 2, 3}
Function signature:
Where(items T, key any, target any)d := []User{{ID: 1, Name: "Hugo"}, {ID: 2, Name: "Lisa"}, {ID: 3, Name: "Iris"}, {ID: 4, Name: "Lisa"}} collect.Where(d, "Name", "Lisa") // []User{{2 Lisa} {4 Lisa}}
Function signature:
Where(items T, key any, operator string, target any)d := []User{{ID: 1, Name: "Hugo"}, {ID: 2, Name: "Lisa"}, {ID: 3, Name: "Iris"}, {ID: 4, Name: "Lisa"}} collect.Where(d, "Name", "!=", "Lisa") // []User{{1 Hugo} {3 Iris}}
-
WhereInremoves elements from the collection that do not exist in the specified sliceExamples
Function signature:
WhereIn(items T, targets []any)d := []int{1, 2, 3, 4} collect.WhereIn(d, []int{2, 3}) // []int{2, 3}
Function signature:
WhereIn(items T, key any, targets []any)d := []User{{ID: 1, Name: "Hugo"}, {ID: 2, Name: "Lisa"}, {ID: 3, Name: "Iris"}, {ID: 4, Name: "Lisa"}} collect.WhereIn(d, "Name", []string{"Hugo", "Iris"}) // []User{{1 Hugo} {3 Iris}}
-
WhereNotInremoves elements from the collection that exist in the specified sliceExamples
Function signature:
WhereNotIn(items T, targets []any)d := []int{1, 2, 3, 4} collect.WhereNotIn(d, []int{2, 3}) // []int{1, 4}
Function signature:
WhereNotIn(items T, key any, targets []any)d := []User{{ID: 1, Name: "Hugo"}, {ID: 2, Name: "Lisa"}, {ID: 3, Name: "Iris"}, {ID: 4, Name: "Lisa"}} collect.WhereNotIn(d, "Name", []string{"Lisa", "Iris"}) // []User{{1 Hugo}}
Exactly the same as slice, you just pass in the array converted to a slice:
arr := [3]int{1, 2, 3}
collect.Len(arr[:])
// or
collect.UseSlice(arr[:]).Len()The corresponding chained function is collect.UseMap()
-
Lengets the number of elements in the mapExamples
d1 := map[string]int{"a": 1, "b": 2, "c": 3} collect.Len(d1) // 3
-
Emptychecks if the map is emptyExamples
var d map[string]int collect.Empty(d) // true
-
Onlygets the elements of the map with the specified keysExamples
d := map[string]int{"a": 1, "b": 2, "c": 3} collect.Only(d, "a") // map[string]int{"a": 1} collect.Only(d, "a", "b") // map[string]int{"a": 1, "b": 2}
-
Exceptgets the elements of the map with the specified keys removedExamples
d := map[string]int{"a": 1, "b": 2, "c": 3} collect.Except(d, "a") // map[string]int{"b": 2, "c": 3} collect.Except(d, "a", "b") // map[string]int{"c": 3}
-
Keysgets all the keys in the mapExamples
d := map[string]int{"a": 1, "b": 2, "c": 3} collect.Keys(d) // []string{"a", "b", "c"}
-
DiffKeyscompares with the given collection and returns the key/value pairs in the given collection that do not exist in the original collectionExamples
d1 := map[string]int{"a": 1, "b": 2, "c": 3} d2 := map[string]int{"b": 22, "c": 33} collect.DiffKeys(d1, d2) // map[string]int{"a": 1}
-
Haschecks if the map contains the specified keyExamples
d := map[string]int{"a": 1} collect.Has(d, "a") // true
-
Getgets the value of the specified key in the mapExamples
d := map[string]int{"a": 1} value, ok := collect.Get(d, "a") // 1, true value, ok := collect.Get(d, "b") // 0, false
-
Putsets the value of the specified key in the mapExamples
d := map[string]int{"a": 1} collect.Put(d, "b", 2) // map[string]int{"a": 1, "b": 2}
-
Pullremoves the specified key from the collection and returns its valueExamples
d := map[string]int{"a": 1, "b": 2} v, ok := collect.Pull(d, "b") // 2, true d // map[string]int{"a": 1}
-
Mergemerges the current map with other mapsExamples
d1 := map[string]int{"a": 1, "b": 2} d2 := map[string]int{"b": 22} d3 := map[string]int{"b": 222, "c": 3} collect.MapMerge(d1, d2) // map[string]int{"a": 1, "b": 22} collect.UseMap(d1).Merge(d2).All() // Equal to the above collect.MapMerge(d1, d2, d3) // map[string]int{"a": 1, "b": 222, "c": 3} collect.UseMap(d1).Merge(d2, d3).All() // Equal to the above
-
Unionunites the current map with other maps, and the items in the original map are given priorityExamples
d1 := map[string]int{"a": 1, "b": 2} d2 := map[string]int{"b": 22, "c": 3} collect.Union(d1, d2) // map[string]int{"a": 1, "b": 2, "c": 3}
The corresponding chained function is collect.UseNumber(),which is a subset of slice and includes, in addition to all the methods of slice, the additional:
-
Sumcalculates the sumExamples
collect.Sum([]float64{1, 3.14}) // 4.14
-
Mincalculates the minimum valueExamples
collect.Min([]int{0, 1, -3}) // -3
-
Maxcalculates the maximum valueExamples
collect.Max([]int{0, 1, -3}) // 1
-
Sortsorts the numbers in the collection in ascending orderExamples
collect.Sort([]float64{1, -4, 0, -4.3}) // []float64{-4.3, -4, 0, 1}
-
SortDescsorts the numbers in the collection in descending orderExamples
collect.SortDesc([]float64{1, -4, 0, -4.3}) // []float64{1, 0, -4, -4.3}
-
Avgcalculates the averageExamples
collect.Avg([]int{1, 2, 3, 4}) // 2.5
-
Mediancalculates the medianExamples
collect.Median([]int{1, 2, 3, 4}) // 2.5
Due to Golang's support for generics, it is not possible to define generic types in methods, so only their function implementations (which do not support chain calls) are listed below:
-
AnyGetgets value of arbitrary types (slices, maps, arrays, structures, and pointers to these) in a non-strict formExamples
m := map[string]int{"a": 1, "b": 2} collect.AnyGet[int](m, "b") // 2 u := &User{"Email": "[email protected]"} collect.AnyGet[string](u, "Email") // [email protected] s := [][]int{{1, 2}, {3, 4}} collect.AnyGet[[]int](s, 1) // []{3, 4}
-
Pluckretrieves all values for a given key. supports all values supported byAnyGetExamples
d := []User{{ID: 33, Name: "Lucy"}, {ID: 193, Name: "Peter"}} collect.Pluck[int](d, "ID") // int[]{33, 193}
-
MapPluckretrieves all values of a given key, only maps are supportedExamples
d := []map[string]int{{"ID": 33, "Score": 10}, {"ID": 193, "Score": 6}} collect.MapPluck(d, "ID") // int[]{33, 193}
-
KeyByretrieves a collection with the value of the given key as the identifier (if there are duplicate keys, only the last one will be kept). Supports all values supported byAnyGetExamples
d := []User{{ID: 33, Name: "Lucy"}, {ID: 193, Name: "Peter"}, {ID: 194, Name: "Peter"}} collect.KeyBy[string](d, "Name") // map[Lucy:{33 Lucy} Peter:{194 Peter}]
-
MapKeyByretrieves the collection with the value of the given key as the identifier (if there are duplicate keys, only the last one will be kept), only maps are supportedExamples
d := []map[string]int{{"ID": 33, "Score": 6}, {"ID": 193, "Score": 10}, {"ID": 194, "Score": 10}} collect.MapKeyBy(d, "Score") // map[6:map[ID:33 Score:6] 10:map[ID:194 Score:10]]
-
GroupBygroups the items in a collection using the value of the given key as the identifier. Supports all values supported byAnyGetExamples
d := []User{{ID: 33, Name: "Lucy"}, {ID: 193, Name: "Peter"}, {ID: 194, Name: "Peter"}} collect.GroupBy[string](d, "Name") // map[Lucy:[{33 Lucy}] Peter:[{193 Peter} {194 Peter}]]
-
MapGroupBygroups items in a collection using the value of the given key as the identifier, only maps are supportedExamples
d := []map[string]int{{"ID": 33, "Score": 6}, {"ID": 193, "Score": 10}, {"ID": 194, "Score": 10}} collect.MapGroupBy(d, "Score") // map[6:[map[ID:33 Score:6]] 10:[map[ID:193 Score:10] map[ID:194 Score:10]]]
-
Countcounts the number of occurrences of each element in the sliceExamples
d := []bool{true, true, false} collect.Count(d) // map[bool]int{true: 2, false: 1}
-
Timescreates a new collection of slice by calling the callback with specified number of timesExamples
collect.Times(3, func(number int) float64 { return float64(number) * 3.14 }) // *SliceCollection{[]float64{3.14, 6.28, 9.42}}
-
SortBycalls a callback for each element and performs an ascending sort by the return value of the callbackExamples
collect.SortBy([]int{2, 1, 3}, func(item, index int) string { return strconv.Itoa(item) }) // *SliceCollection{[]int{1, 2, 3}}
-
SortByDesccalls a callback for each element and performs a descending sort by the return value of the callbackExamples
collect.SortByDesc([]int{2, 1, 3}, func(item, index int) string { return strconv.Itoa(item) }) // *SliceCollection{[]int{3, 2, 1}}
go-collection is MIT licensed.