A generic collection for Go with a few convenient methods.
There are far more comprehensive modules out there, but this one works quite well for my purposes.
go get github.com/wilhelm-murdoch/go-collection
- New
- Items
- Sort
- Filter
- Batch
- Slice
- Contains
- ContainsBy
- PushDistinct
- Shift
- Unshift
- At
- IsEmpty
- Empty
- Find
- FindIndex
- RandomIndex
- Random
- LastIndexOf
- Reduce
- Reverse
- Some
- None
- All
- Push
- Pop
- Length
- Map
- Each
- Concat
- InsertAt
- InsertBefore
- InsertAfter
- AtFirst
- AtLast
- Count
- CountBy
- MarshalJSON
New returns a new collection of type T containing the specified items and their types. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fruits := collection.New("apple", "orange", "strawberry", "cherry", "banana", "apricot")
fmt.Println("Fruits:", fruits.Length())
fruits.Each(func(index int, item string) bool {
fmt.Println("-", item)
return false
})
}
// Output:
// Fruits: 6
// - apple
// - orange
// - strawberry
// - cherry
// - banana
// - apricot
Items returns the current collection's set of items.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("apple", "orange", "strawberry")
for i, item := range c.Items() {
fmt.Println(i, item)
}
}
// Output:
// 0 apple
// 1 orange
// 2 strawberry
Sort sorts the collection given the provided less function. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
numbers := collection.New(1, 4, 2, 3)
fmt.Println("Unsorted:")
numbers.Each(func(i, n int) bool {
fmt.Print(" ", n)
return false
})
fmt.Println("\nSorted:")
numbers.Sort(func(i, j int) bool {
left, _ := numbers.At(i)
right, _ := numbers.At(j)
return left < right
}).Each(func(i, n int) bool {
fmt.Print(" ", n)
return false
})
}
// Output:
// Unsorted:
// 1 4 2 3
// Sorted:
// 1 2 3 4
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
names := collection.New("wilhelm", "peter", "josh", "luke", "rob")
fmt.Println("Unsorted:")
fmt.Println(strings.Join(names.Items(), ","))
names.Sort(func(i, j int) bool {
left, _ := names.At(i)
right, _ := names.At(j)
return left < right
})
fmt.Println("Sorted:")
fmt.Println(strings.Join(names.Items(), ","))
}
// Output:
// Unsorted:
// wilhelm,peter,josh,luke,rob
// Sorted:
// josh,luke,peter,rob,wilhelm
Filter returns a new collection with items that have passed predicate check. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("apple", "orange", "strawberry").Filter(func(item string) bool {
return item == "apple"
})
c.Each(func(index int, item string) bool {
fmt.Println(item)
return false
})
}
// Output:
// apple
func (c *Collection[T]) Batch(f func(int, int, T), batchSize int) *Collection[T]
#collection.go:55:89
#
Batch exposes a very simple parallelized batch processor for a collection. Defining a batchSize
will break the current collection into groups of jobs that will be processed in parallel by Goroutines managed by an error group. The specified function f
will be executed for each job in each batch. The signature for this function is func(currentBatchIndex, currentJobIndex int, job T)
. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
type Job struct {
Timestamp int64
Processed bool
}
jobs := make([]*Job, 0)
for i := 1; i <= 100; i++ {
jobs = append(jobs, &Job{time.Now().UnixNano(), false})
}
c1 := collection.New(jobs...)
c1.Batch(func(b, j int, job *Job) {
job.Processed = true
}, 5)
processed := c1.All(func(i int, job *Job) bool {
return job.Processed == true
})
fmt.Printf("processed %d/%d jobs:%v\n", c1.Length(), c1.Length(), processed)
}
// Output:
// processed 100/100 jobs:true
Slice returns a new collection containing a slice of the current collection starting with from
and to
indexes. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
collection.New("apple", "orange", "strawberry").Slice(0, 2).Each(func(i int, item string) bool {
fmt.Println(item)
return false
})
}
// Output:
// apple
// orange
Contains returns true if an item is present in the current collection. This method makes use of reflect.DeepEqual
to ensure an absolute match. If you wish to check by a specific field within a slice of objects, use collection.ContainsBy
instead.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fmt.Println(collection.New("apple", "orange", "strawberry").Contains("horse"))
}
// Output:
// false
func (c *Collection[T]) ContainsBy(f func(i int, item T) bool) (found bool)
#collection.go:122:130
#
ContainsBy returns true if an item in the current collection matches the specified predicate function. This is useful if you have a slice of objects and you wish to check the existence of a specific field value.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
type Person struct {
Name string
Age int
}
people := []Person{
{"wilhelm", 31},
{"luke", 42},
{"rob", 17},
{"peter", 26},
{"josh", 26},
}
fmt.Println(collection.New(people...).ContainsBy(func(i int, p Person) bool {
return p.Age < 20
}))
}
// Output:
// true
PushDistinct method appends one or more distinct items to the current collection, returning the new length. Items that already exist within the current collection will be ignored. You can check for this by comparing old v.s. new collection lengths.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("apple", "orange", "strawberry")
c.PushDistinct("orange", "orange", "watermelon")
c.Each(func(index int, item string) bool {
fmt.Println(item)
return false
})
}
// Output:
// apple
// orange
// strawberry
// watermelon
Shift method removes the first item from the current collection, then returns that item.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fmt.Println(collection.New("apple", "orange", "strawberry").Shift())
}
// Output:
// apple
Unshift method appends one item to the beginning of the current collection, returning the new length of the collection.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("apple", "orange", "strawberry")
fmt.Println("Length Current:", c.Length())
fmt.Println("Length New: ", c.Unshift("horse"))
c.Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// Length Current: 3
// Length New: 4
// 0 horse
// 1 apple
// 2 orange
// 3 strawberry
At attempts to return the item associated with the specified index for the current collection along with a boolean value stating whether or not an item could be found.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
item, ok := collection.New("apple", "orange", "strawberry").At(1)
fmt.Println(item, ok)
}
// Output:
// orange true
IsEmpty returns a boolean value describing the empty state of the current collection.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("lonely")
fmt.Println(c.IsEmpty())
c.Empty()
fmt.Println(c.IsEmpty())
}
// Output:
// false
// true
Empty will reset the current collection to zero items. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fmt.Println(collection.New("apple", "orange", "strawberry").Empty().Length())
}
// Output:
// 0
Find returns the first item in the provided current collectionthat satisfies the provided testing function. If no items satisfy the testing function, a value is returned.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fmt.Println(collection.New("apple", "orange", "strawberry").Find(func(i int, item string) bool {
return item == "orange"
}))
}
// Output:
// orange
FindIndex returns the index of the first item in the specified collection that satisfies the provided testing function. Otherwise, it returns -1, indicating that no element passed the test.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fmt.Println(collection.New("apple", "orange", "strawberry").FindIndex(func(i int, item string) bool {
return item == "orange"
}))
}
// Output:
// 1
RandomIndex returns the index associated with a random item from the current collection.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
index := collection.New("apple", "orange", "strawberry").RandomIndex()
fmt.Println("My random index is:", index)
}
Random returns a random item from the current collection.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
item, ok := collection.New("apple", "orange", "strawberry").Random()
if ok {
fmt.Println("My random item is:", item)
}
}
LastIndexOf returns the last index at which a given item can be found in the current collection, or -1 if it is not present.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fmt.Println(collection.New("apple", "orange", "orange", "strawberry").LastIndexOf("orange"))
}
// Output:
// 2
func (c *Collection[T]) Reduce(f func(i int, item, accumulator T) T) (out T)
#collection.go:243:249
#
Reduce reduces a collection to a single value. The value is calculated by accumulating the result of running each item in the collection through an accumulator function. Each successive invocation is supplied with the return value returned by the previous call.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
acc := collection.New("apple", "orange", "strawberry").Reduce(func(i int, item, accumulator string) string {
return accumulator + item
})
fmt.Println(acc)
}
// Output:
// appleorangestrawberry
Reverse the current collection so that the first item becomes the last, the second item becomes the second to last, and so on. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
collection.New("apple", "orange", "orange", "strawberry").Reverse().Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// 0 strawberry
// 1 orange
// 2 orange
// 3 apple
Some returns a true value if at least one item within the current collection resolves to true as defined by the predicate function f.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
found := collection.New("apple", "orange", "strawberry").Some(func(i int, item string) bool {
return item == "orange"
})
fmt.Println("Found \"orange\"?", found)
}
// Output:
// Found "orange"? true
None returns a true value if no items within the current collection resolve to true as defined by the predicate function f.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
found := collection.New("apple", "orange", "strawberry").Some(func(i int, item string) bool {
return item == "blackberry"
})
fmt.Println("Found \"blackberry\"?", found)
}
// Output:
// Found "blackberry"? false
All returns a true value if all items within the current collection resolve to true as defined by the predicate function f.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("apple", "orange", "strawberry")
fmt.Println("Contains all items?", c.All(func(i int, item string) bool {
return c.Contains(item)
}))
}
// Output:
// Contains all items? true
Push method appends one or more items to the end of a collection, returning the new length.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("apple", "orange", "strawberry")
fmt.Println("Collection Length:", c.Push("blueberry", "watermelon"))
c.Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// Collection Length: 5
// 0 apple
// 1 orange
// 2 strawberry
// 3 blueberry
// 4 watermelon
Pop method removes the last item from the current collection and then returns that item.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
item, ok := collection.New("apple", "orange", "strawberry").Pop()
fmt.Println(item, ok)
}
// Output:
// strawberry true
Length returns number of items associated with the current collection.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
fmt.Println("Collection Length:", collection.New("apple", "orange", "strawberry").Length())
}
// Output:
// Collection Length: 3
Map method creates to a new collection by using callback invocation result on each array item. On each iteration f is invoked with arguments: index and current item. It should return the new collection. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
c := collection.New("apple", "orange", "strawberry").Map(func(i int, item string) string {
return fmt.Sprintf("The %s is yummo!", item)
})
c.Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// 0 The apple is yummo!
// 1 The orange is yummo!
// 2 The strawberry is yummo!
Each iterates through the specified list of items executes the specified callback on each item. This method returns the current instance of collection. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
collection.New("apple", "orange", "strawberry").Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// 0 apple
// 1 orange
// 2 strawberry
Concat merges two slices of items. This method returns the current instance collection with the specified slice of items appended to it. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
collection.New("apple", "orange", "strawberry").Concat([]string{"dog", "cat", "horse"}).Each(func(index int, item string) bool {
fmt.Println(item)
return false
})
}
// Output:
// apple
// orange
// strawberry
// dog
// cat
// horse
InsertAt inserts the specified item at the specified index and returns the current collection. If the specified index is less than 0, 0 is used. If an index greater than the size of the collectio nis specified, c.Push is used instead. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
collection.New("apple", "orange", "strawberry").InsertAt("banana", 2).Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// 0 apple
// 1 orange
// 2 banana
// 3 strawberry
InsertBefore inserts the specified item before the specified index and returns the current collection. If the specified index is less than 0, c.Unshift is used. If an index greater than the size of the collection is specified, c.Push is used instead. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
collection.New("apple", "orange", "strawberry").InsertBefore("banana", 2).Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// 0 apple
// 1 banana
// 2 orange
// 3 strawberry
InsertAfter inserts the specified item after the specified index and returns the current collection. If the specified index is less than 0, 0 is used. If an index greater than the size of the collectio nis specified, c.Push is used instead. ( Chainable )
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
collection.New("apple", "orange", "strawberry").InsertAfter("banana", 1).Each(func(i int, item string) bool {
fmt.Println(i, item)
return false
})
}
// Output:
// 0 apple
// 1 orange
// 2 banana
// 3 strawberry
AtFirst attempts to return the first item of the collection along with a boolean value stating whether or not an item could be found.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
first, ok := collection.New("apple", "orange", "strawberry").AtFirst()
fmt.Println(first, ok)
}
// Output:
// apple true
AtLast attempts to return the last item of the collection along with a boolean value stating whether or not an item could be found.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
last, ok := collection.New("apple", "orange", "strawberry").AtLast()
fmt.Println(last, ok)
}
// Output:
// strawberry true
Count counts the number of items in the collection that compare equal to value.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
count := collection.New("apple", "orange", "orange", "strawberry").Count("orange")
fmt.Println("Orange Count:", count)
}
// Output:
// Orange Count: 2
CountBy counts the number of items in the collection for which predicate is true.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
count := collection.New("apple", "orange", "strawberry", "blueberry").CountBy(func(item string) bool {
return strings.HasSuffix(item, "berry")
})
fmt.Println("Berry Types:", count)
}
// Output:
// Berry Types: 2
MarshalJSON implements the Marshaler interface so the current collection's items can be marshalled into valid JSON.
package main
import (
"fmt"
"strings"
"github.com/wilhelm-murdoch/go-collection"
)
func main() {
var buffer strings.Builder
encoder := json.NewEncoder(&buffer)
encoder.Encode(collection.New("apple", "orange", "strawberry"))
fmt.Println(buffer.String())
}
// Output:
// ["apple","orange","strawberry"]
Documentation generated by Gadget.
Copyright © 2022 Wilhelm Murdoch.
This project is MIT licensed.