A production-grade Go package providing comprehensive utilities for working with Go slices. Built with modern Go features including generics, proper error handling, and extensive test coverage.
- Type Safety: Uses Go generics for compile-time type safety
- Comprehensive Operations: Comparison, merging, finding differences, statistics, and more
- Error Handling: Proper error handling instead of panics
- Performance Optimized: Efficient algorithms with memoization for struct comparisons
- Thread Safe: Concurrent access support with proper synchronization
- Well Tested: Extensive test coverage with benchmarks
- Production Ready: Industry-standard code structure and documentation
go get github.com/devrob-go/sliceutilpackage main
import (
"fmt"
"github.com/devrob-go/sliceutil"
)
func main() {
// Compare slices
a := []int{1, 2, 3, 4, 5}
b := []int{1, 2, 3, 4, 5}
if sliceutil.CompareSlices(a, b) {
fmt.Println("Slices are equal!")
}
// Find differences
c := []int{1, 2, 3, 6, 7}
differences := sliceutil.FindDifferences(a, c)
fmt.Printf("Differences: %v\n", differences) // [4, 5, 6, 7]
// Merge and sort
merged := sliceutil.MergeSlicesInt(a, c, sliceutil.OrderAsc)
fmt.Printf("Merged: %v\n", merged) // [1, 1, 2, 2, 3, 3, 4, 5, 6, 7]
// Get statistics
stats, err := sliceutil.GetSliceStats(a)
if err == nil {
fmt.Printf("Length: %d, Min: %v, Max: %v, Sum: %v, Average: %.2f\n",
stats.Length, stats.Min, stats.Max, stats.Sum, stats.Average)
}
}Compares two slices for equality in values and order.
a := []int{1, 2, 3}
b := []int{1, 2, 3}
equal := sliceutil.CompareSlices(a, b) // trueProvides detailed comparison results including difference locations.
result := sliceutil.CompareSlicesWithResult(a, b)
if !result.Equal {
fmt.Printf("Slices differ: %s\n", result.Message)
fmt.Printf("Difference count: %d\n", result.Details["difference_count"])
}Deep comparison of structs with memoization for performance.
type Person struct {
Name string
Age int
}
a := Person{Name: "Alice", Age: 30}
b := Person{Name: "Alice", Age: 30}
equal := sliceutil.CompareStructs(a, b) // trueReturns unique values from both slices that are not in the other.
a := []int{1, 2, 3, 4}
b := []int{3, 4, 5, 6}
differences := sliceutil.FindDifferences(a, b) // [1, 2, 5, 6]Finds the maximum value in an int slice.
max, err := sliceutil.MaxInt([]int{1, 5, 3, 9, 2})
if err == nil {
fmt.Printf("Max: %d\n", max) // 9
}Finds the minimum value in an int slice.
min, err := sliceutil.MinInt([]int{1, 5, 3, 9, 2})
if err == nil {
fmt.Printf("Min: %d\n", min) // 1
}Calculates the sum of all integers in a slice.
sum, err := sliceutil.SumInt([]int{1, 2, 3, 4, 5})
if err == nil {
fmt.Printf("Sum: %d\n", sum) // 15
}Calculates the average of all integers in a slice.
avg, err := sliceutil.AverageInt([]int{1, 2, 3, 4, 5})
if err == nil {
fmt.Printf("Average: %.2f\n", avg) // 3.00
}Merges two int slices with specified sorting order.
a := []int{5, 1, 3}
b := []int{4, 2, 6}
merged := sliceutil.MergeSlicesInt(a, b, sliceutil.OrderAsc)
// Result: [1, 2, 3, 4, 5, 6]Merges two string slices with specified sorting order.
a := []string{"banana", "apple"}
b := []string{"cherry", "date"}
merged := sliceutil.MergeSlicesString(a, b, sliceutil.OrderAsc)
// Result: ["apple", "banana", "cherry", "date"]Generic merge function with custom comparison logic.
type Person struct {
Name string
Age int
}
a := []Person{{Name: "Alice", Age: 30}, {Name: "Bob", Age: 25}}
b := []Person{{Name: "Charlie", Age: 35}}
less := func(a, b Person) bool { return a.Age < b.Age }
merged := sliceutil.MergeSlicesGeneric(a, b, sliceutil.OrderAsc, less)Checks if a slice contains a specific element.
slice := []int{1, 2, 3, 4, 5}
contains := sliceutil.Contains(slice, 3) // trueReturns the index of the first occurrence of an element.
slice := []int{1, 2, 3, 4, 5}
index := sliceutil.IndexOf(slice, 3) // 2Removes duplicate elements while preserving order.
slice := []int{1, 2, 2, 3, 3, 4}
unique := sliceutil.RemoveDuplicates(slice) // [1, 2, 3, 4]Reverses the order of elements in a slice (modifies original).
slice := []int{1, 2, 3, 4, 5}
sliceutil.Reverse(slice)
// slice is now [5, 4, 3, 2, 1]Creates a reversed copy without modifying the original.
original := []int{1, 2, 3, 4, 5}
reversed := sliceutil.ReverseCopy(original)
// original is unchanged, reversed is [5, 4, 3, 2, 1]Provides comprehensive statistical information about a slice.
stats, err := sliceutil.GetSliceStats([]int{1, 2, 3, 4, 5})
if err == nil {
fmt.Printf("Length: %d\n", stats.Length)
fmt.Printf("Min: %v\n", stats.Min)
fmt.Printf("Max: %v\n", stats.Max)
fmt.Printf("Sum: %v\n", stats.Sum)
fmt.Printf("Average: %v\n", stats.Average)
fmt.Printf("Has Duplicates: %t\n", stats.HasDuplicates)
}Clears the memoization cache for struct comparisons.
sliceutil.ClearStructCache()Returns statistics about the struct comparison cache.
stats := sliceutil.GetStructCacheStats()
fmt.Printf("Cache size: %d\n", stats["cache_size"])The package uses proper error handling instead of panics. Common errors include:
ErrEmptySlice: Returned when a slice is empty but cannot beErrNilSlice: Returned when a slice is nil but cannot beErrTypeMismatch: Returned when slice types don't matchErrUnsupportedType: Returned when a type is not supported
max, err := sliceutil.MaxInt([]int{})
if err != nil {
switch {
case errors.Is(err, sliceutil.ErrEmptySlice):
fmt.Println("Cannot find max in empty slice")
case errors.Is(err, sliceutil.ErrNilSlice):
fmt.Println("Cannot find max in nil slice")
}
}- Slice Comparison: O(n) time complexity for basic comparison
- Struct Comparison: Uses memoization to avoid repeated comparisons
- Merge Operations: O((n + m) * log(n + m)) time complexity due to sorting
- Memory Usage: Efficient memory usage with minimal allocations
- Struct Comparison Cache: Thread-safe with read-write mutex
- Slice Operations: All slice operations are thread-safe
- Concurrent Access: Safe for concurrent use in multiple goroutines
Run the test suite:
go test ./...Run tests with coverage:
go test -cover ./...Run benchmarks:
go test -bench=. ./...See the examples/ directory for more detailed usage examples.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- v1.0.0: Initial release with comprehensive slice utilities
- Comprehensive comparison functions
- Merge and sort operations
- Statistical analysis functions
- Thread-safe struct comparison with memoization
- Extensive test coverage
For questions, issues, or contributions, please open an issue on GitHub or submit a pull request.