A simple, generic, and easy-to-use Go library that provides a rich set of utility functions for managing and manipulating slices. It wraps native slices and offers an intuitive API for performing common operations such as adding, removing, filtering, and modifying elements.
- Simple and Intuitive Syntax: Easy-to-use methods for operations like push, pop, and insertion.
- Flexible Types: Works with any type of slice thanks to Go’s generics.
- Advanced Operations: Support for advanced functionality like filtering, sorting, shuffling, and reversing.
- Safe Indexing: Support for negative indexes and index-bounds checks.
- No Extra Allocations: This library is designed to avoid unnecessary memory allocations. Operations like shifting, popping, deleting, or inserting elements reuse the existing slice capacity wherever possible. This helps optimize memory usage and keeps performance consistent, especially in tight loops or high-frequency operations.
- Memory Zeroing: When elements are deleted, shifted, or popped, the library automatically "zeroes out" the removed elements by setting them to the zero value of their type. This prevents potential memory leaks and ensures that the garbage collector can efficiently clean up unused elements.
go get github.com/go-slice/slice
There are multiple ways to create a slice, either with or without predefined elements:
To create an empty slice of integers:
package main
import (
"fmt"
"github.com/go-slice/slice"
)
func main() {
// Create an empty slice
var s slice.Slice[int]
// Add some elements
s.Push(4, 5, 6)
fmt.Println(s) // Output: [4 5 6]
}
You can also initialize the slice with elements using the following syntax:
// Create a slice with predefined elements
s := slice.Slice[int]{4, 5, 6}
fmt.Println(s) // Output: [4 5 6]
To create a slice with a predefined capacity (which can help avoid redundant allocations when you know the size in advance):
// Create a slice with a capacity of 100 but no initial elements
s := slice.FromRaw(make([]int, 0, 100))
// Now you can add elements without triggering new allocations until the slice exceeds the capacity
s.Push(1, 2, 3)
fmt.Println(s) // Output: [1 2 3]
Append or remove elements from the end of the slice.
var s slice.Slice[int]
// Push 3 elements to the slice
s.Push(10, 20, 30)
fmt.Println(s) // Output: [10 20 30]
// Pop the last element
val, _ := s.Pop()
fmt.Println(val) // Output: 30
fmt.Println(s) // Output: [10 20]
Add or remove elements from the beginning of the slice.
var s slice.Slice[int]
// Push elements to the slice
s.Push(3, 4, 5)
// Unshift adds elements to the beginning of the slice
s.Unshift(1, 2)
fmt.Println(s) // Output: [1 2 3 4 5]
// Shift removes the first element and returns it
val, _ := s.Shift()
fmt.Println(val) // Output: 1
fmt.Println(s) // Output: [2 3 4 5]
You can delete a single element from any position in the slice. For example, deleting the element at index 2
:
var s slice.Slice[int]
// Push elements to the slice
s.Push(1, 2, 3, 4, 5)
// Delete 1 element starting at index 2
s.Delete(2, 1)
fmt.Println(s) // Output: [1 2 4 5]
You can use a negative index to delete the last element. This can be done using s.Delete(-1, 1)
or s.DeleteOne(-1)
, as both are equivalent when removing the last element:
var s slice.Slice[int]
// Push elements to the slice
s.Push(1, 2, 3, 4, 5)
// Delete 1 element starting from the last index (-1)
s.Delete(-1, 1)
fmt.Println(s) // Output: [1 2 3 4]
// Alternatively, delete the last element with DeleteOne
s.DeleteOne(-1)
Insert elements at a specific index.
var s slice.Slice[string]
// Push initial elements to the slice
s.Push("one", "three")
// Insert "two" at index 1
s.Insert(1, "two")
fmt.Println(s) // Output: [one two three]
Replace a section of the slice with new elements.
var s slice.Slice[string]
// Push elements to the slice
s.Push("a", "b", "b", "b", "e")
// Replace the slice from index 2 with "c" and "d"
s.Replace(2, "c", "d")
fmt.Println(s) // Output: [a b c d e]
Remove elements based on a custom condition.
var s slice.Slice[int]
// Push elements to the slice
s.Push(1, 2, 3, 4, 5, 6)
// Keep only even numbers using the Filter method
s.Filter(func(_ int, val int) bool {
return val%2 == 0
})
fmt.Println(s) // Output: [2 4 6]
Reverse the order of elements in the slice.
var s slice.Slice[int]
// Push elements to the slice
s.Push(1, 2, 3, 4, 5)
// Reverse the order of the slice
s.Reverse()
fmt.Println(s) // Output: [5 4 3 2 1]
Sort the slice using a custom comparison function.
var s slice.Slice[int]
// Push elements to the slice
s.Push(5, 3, 1, 4, 2)
// Sort the slice in ascending order
s.Sort(func(a, b int) int {
return a - b
})
fmt.Println(s) // Output: [1 2 3 4 5]
Randomly shuffle the elements in the slice.
import "math/rand"
var s slice.Slice[int]
// Push elements to the slice
s.Push(1, 2, 3, 4, 5)
// Shuffle the slice using a random integer generator
s.Shuffle(rand.Intn)
fmt.Println(s) // Output: [3 5 1 4 2] (shuffled randomly)
Get an element using a negative index, counting from the end.
var s slice.Slice[int]
// Push elements to the slice
s.Push(1, 2, 3, 4, 5)
// Get the last element using a negative index (-1)
val, _ := s.Get(-1)
fmt.Println(val) // Output: 5
Clone()
: Create a copy of the slice.Len()
: Get the length of the slice.Cap()
: Get the capacity of the slice.Empty()
: Check if the slice is empty.Raw()
: Retrieve the underlying Go slice.
This project is licensed under the MIT License.
Feel free to use, modify, and contribute!