You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.5 KiB
Go

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
}