more set tests, started writing slice stuff
							parent
							
								
									99865a3ccd
								
							
						
					
					
						commit
						21e82bb2b5
					
				@ -1,3 +1,5 @@
 | 
			
		||||
# collections-go
 | 
			
		||||
 | 
			
		||||
A dependency-free package of generic Go collection data structures. Compatible with Go 1.18 and above.
 | 
			
		||||
A dependency-free package of generic Go collection data structures. Compatible with Go 1.18 and above. Strives for the most optimal solutions available with lowest number of allocations.
 | 
			
		||||
 | 
			
		||||
Contributions are not currently open as this project is in active early development.
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,9 @@
 | 
			
		||||
package collections
 | 
			
		||||
 | 
			
		||||
// A UnaryPredicate is a function that takes a single element of type
 | 
			
		||||
// T and returns a boolean.
 | 
			
		||||
type UnaryPredicate[T any] func(T) bool
 | 
			
		||||
 | 
			
		||||
// A UnaryOperator is a function that takes a single element of type
 | 
			
		||||
// T and returns an element of type T.
 | 
			
		||||
type UnaryOperator[T any] func(T) T
 | 
			
		||||
@ -0,0 +1,87 @@
 | 
			
		||||
package collections
 | 
			
		||||
 | 
			
		||||
/*****************
 | 
			
		||||
This section contains the alias API, which allows for receiver-style calling
 | 
			
		||||
convention.
 | 
			
		||||
*****************/
 | 
			
		||||
 | 
			
		||||
// Slice is an alias over a Go slice that enables a direct receiver-style API.
 | 
			
		||||
// For Slice, T must satisfy comparable.
 | 
			
		||||
type Slice[T comparable] []T
 | 
			
		||||
 | 
			
		||||
// Check if a slice contains an element. Calls SliceContains.
 | 
			
		||||
func (sl Slice[T]) Contains(needle T) bool {
 | 
			
		||||
	return SliceContains(sl, needle)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run an operator on every element in the slice, and return a slice that
 | 
			
		||||
// contains the result of every operation. Calls SliceMap.
 | 
			
		||||
func (sl Slice[T]) Map(op UnaryOperator[T]) Slice[T] {
 | 
			
		||||
	return SliceMap(sl, op)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AnySlice is an alias over a Go slice that does not enforce T satisfying
 | 
			
		||||
// comparable. Any method that relies on comparison of elements is not
 | 
			
		||||
// available for AnySlice.
 | 
			
		||||
type AnySlice[T any] []T
 | 
			
		||||
 | 
			
		||||
// Run an operator on every element in the slice, and return a slice that
 | 
			
		||||
// contains the result of every operation. Calls SliceMap.
 | 
			
		||||
func (sl AnySlice[T]) Map(op UnaryOperator[T]) AnySlice[T] {
 | 
			
		||||
	return SliceMap(sl, op)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*****************
 | 
			
		||||
This section contains the direct API, which is a more traditional Go style
 | 
			
		||||
API.
 | 
			
		||||
*****************/
 | 
			
		||||
 | 
			
		||||
// Check if a slice contains an element.
 | 
			
		||||
//
 | 
			
		||||
// Time Complexity: O(n)
 | 
			
		||||
// Space Complexity: O(1)
 | 
			
		||||
// Allocations: None.
 | 
			
		||||
func SliceContains[T comparable](haystack []T, needle T) bool {
 | 
			
		||||
	for i := 0; i < len(haystack); i++ {
 | 
			
		||||
		if haystack[i] == needle {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run an operator on every element in the slice, and return a slice that
 | 
			
		||||
// contains the result of every operation.
 | 
			
		||||
//
 | 
			
		||||
// Time Complexity: O(n * m) (where m = complexity of operator)
 | 
			
		||||
// Space Complexity: O(n)
 | 
			
		||||
// Allocations: 1 slice, n elements.
 | 
			
		||||
func SliceMap[T any](sl []T, op UnaryOperator[T]) []T {
 | 
			
		||||
	result := make([]T, len(sl))
 | 
			
		||||
	for i := 0; i < len(sl); i++ {
 | 
			
		||||
		result[i] = op(sl[i])
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run a predicate on every element in the slice, and return a slice
 | 
			
		||||
// that contains every element for which the predicate was true.
 | 
			
		||||
//
 | 
			
		||||
// Time Complexity: O(n * m) (where m = complexity of predicate)
 | 
			
		||||
// Space Complexity: O(n)
 | 
			
		||||
// Allocations: 2 slice, first with n elements, second is the first slice
 | 
			
		||||
// resized if necessary.
 | 
			
		||||
func SliceFilter[T any](sl []T, pred UnaryPredicate[T]) []T {
 | 
			
		||||
	result := make([]T, len(sl))
 | 
			
		||||
	resultIdx := 0
 | 
			
		||||
	for i := 0; i < len(sl); i++ {
 | 
			
		||||
		if pred(sl[i]) {
 | 
			
		||||
			result[resultIdx] = sl[i]
 | 
			
		||||
			resultIdx++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if resultIdx < len(result)-1 {
 | 
			
		||||
		result = result[:resultIdx]
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,13 @@
 | 
			
		||||
package collections_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/RageCage64/collections-go"
 | 
			
		||||
	"github.com/RageCage64/go-assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestSliceContainsDirect(t *testing.T) {
 | 
			
		||||
	x := []int{1, 2, 3}
 | 
			
		||||
	assert.Assert(t, collections.SliceContains(x, 1), "it didn't")
 | 
			
		||||
}
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue