189 lines
6.4 KiB
Go
189 lines
6.4 KiB
Go
package array
|
|
|
|
// MapWithError transforms each element in the input slice to a new type, with error handling.
|
|
//
|
|
// It applies the selector function to each element in the input slice and its index.
|
|
// If the selector function returns an error for any element, the function immediately
|
|
// returns that error and a nil slice. Otherwise, it returns a new slice containing
|
|
// all transformed elements and nil error.
|
|
//
|
|
// Generic parameters:
|
|
// - TIn: The type of elements in the input slice
|
|
// - TOut: The type of elements in the output slice
|
|
//
|
|
// Parameters:
|
|
// - arr: The input slice to transform
|
|
// - selector: A function that takes an element and its index, returning a pointer to
|
|
// the transformed value and an error
|
|
//
|
|
// Returns:
|
|
// - A slice of transformed elements
|
|
// - An error if the transformation failed for any element
|
|
func MapWithError[TIn any, TOut any](arr []TIn, selector func(val TIn, index int) (*TOut, error)) ([]TOut, error) {
|
|
var output []TOut
|
|
for i := range arr {
|
|
out, err := selector(arr[i], i)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
output = append(output, *out)
|
|
}
|
|
return output, nil
|
|
}
|
|
|
|
// Map transforms each element in the input slice to a new type.
|
|
//
|
|
// It applies the selector function to each element in the input slice and its index,
|
|
// returning a new slice containing all transformed elements.
|
|
//
|
|
// Generic parameters:
|
|
// - TIn: The type of elements in the input slice
|
|
// - TOut: The type of elements in the output slice
|
|
//
|
|
// Parameters:
|
|
// - arr: The input slice to transform
|
|
// - selector: A function that takes an element and its index, returning the transformed value
|
|
//
|
|
// Returns:
|
|
// - A slice of transformed elements
|
|
func Map[TIn any, TOut any](arr []TIn, selector func(val TIn, index int) TOut) []TOut {
|
|
var output []TOut
|
|
for i := range arr {
|
|
out := selector(arr[i], i)
|
|
output = append(output, out)
|
|
}
|
|
return output
|
|
}
|
|
|
|
// MapD transforms each value in a map to an element in a slice.
|
|
//
|
|
// It applies the selector function to each value and key in the input map,
|
|
// returning a slice containing all transformed values.
|
|
//
|
|
// Generic parameters:
|
|
// - TKey: The type of keys in the input map (must be comparable)
|
|
// - TIn: The type of values in the input map
|
|
// - TOut: The type of elements in the output slice
|
|
//
|
|
// Parameters:
|
|
// - m: The input map to transform
|
|
// - selector: A function that takes a value and its key, returning the transformed value
|
|
//
|
|
// Returns:
|
|
// - A slice of transformed values
|
|
func MapD[TKey comparable, TIn any, TOut any](m map[TKey]TIn, selector func(val TIn, key TKey) TOut) []TOut {
|
|
var output []TOut
|
|
for i := range m {
|
|
out := selector(m[i], i)
|
|
output = append(output, out)
|
|
}
|
|
return output
|
|
}
|
|
|
|
// ForEach applies a function to each element in the input slice.
|
|
//
|
|
// Unlike Map, ForEach modifies elements in place by providing a pointer to each element.
|
|
// This function does not return a new slice.
|
|
//
|
|
// Generic parameters:
|
|
// - TIn: The type of elements in the input slice
|
|
//
|
|
// Parameters:
|
|
// - arr: The input slice whose elements will be processed
|
|
// - selector: A function that takes a pointer to an element and its index
|
|
func ForEach[TIn any](arr []TIn, selector func(val *TIn, index int)) {
|
|
for i := 0; i < len(arr); i++ {
|
|
selector(&arr[i], i)
|
|
}
|
|
}
|
|
|
|
// MapMany transforms and flattens a nested collection structure.
|
|
//
|
|
// It first applies the collectionSelector to each element in the input slice to produce
|
|
// an inner collection. Then it applies the resultSelector to each inner element along with
|
|
// the original element, flattening the result into a single output slice. If resultSelector
|
|
// returns nil for any element, that element is skipped in the output.
|
|
//
|
|
// Generic parameters:
|
|
// - TIn: The type of elements in the input slice
|
|
// - TC: The type of elements in the inner collections
|
|
// - TOut: The type of elements in the output slice
|
|
//
|
|
// Parameters:
|
|
// - m: The input slice to transform
|
|
// - collectionSelector: A function that produces an inner collection from each input element
|
|
// - resultSelector: A function that transforms each inner element along with its parent element
|
|
//
|
|
// Returns:
|
|
// - A flattened slice of transformed elements
|
|
func MapMany[TIn any, TC any, TOut any](m []TIn, collectionSelector func(TIn) []TC, resultSelector func(TIn, TC) *TOut) []TOut {
|
|
var output []TOut
|
|
|
|
for i := range m {
|
|
out := collectionSelector(m[i])
|
|
for _, v := range out {
|
|
result := resultSelector(m[i], v)
|
|
if result == nil {
|
|
continue
|
|
}
|
|
output = append(output, *result)
|
|
}
|
|
}
|
|
return output
|
|
}
|
|
|
|
// MapManyD transforms and flattens values from a map.
|
|
//
|
|
// It first applies the collectionSelector to each value in the input map to produce
|
|
// an inner collection. Then it applies the resultSelector to each inner element,
|
|
// flattening the results into a single output slice.
|
|
//
|
|
// Generic parameters:
|
|
// - TKey: The type of keys in the input map (must be comparable)
|
|
// - TIn: The type of values in the input map
|
|
// - TC: The type of elements in the inner collections
|
|
// - TOut: The type of elements in the output slice
|
|
//
|
|
// Parameters:
|
|
// - m: The input map to transform
|
|
// - collectionSelector: A function that produces an inner collection from each input value
|
|
// - resultSelector: A function that transforms each inner element
|
|
//
|
|
// Returns:
|
|
// - A flattened slice of transformed elements
|
|
func MapManyD[TKey comparable, TIn any, TC any, TOut any](m map[TKey]TIn, collectionSelector func(TIn) []TC, resultSelector func(TC) TOut) []TOut {
|
|
var output []TOut
|
|
|
|
for i := range m {
|
|
out := collectionSelector(m[i])
|
|
for _, v := range out {
|
|
output = append(output, resultSelector(v))
|
|
}
|
|
}
|
|
return output
|
|
}
|
|
|
|
// ToMap converts a slice of items into a map using the provided key and value selectors.
|
|
// TKey is the type of the keys in the resulting map, TIn is the type of items in the input slice,
|
|
// and TOut is the type of the values in the resulting map.
|
|
func ToMap[TKey comparable, TIn any, TOut any](
|
|
items []TIn,
|
|
keySelector func(TIn) TKey,
|
|
valueSelector func(TIn) TOut,
|
|
) map[TKey]TOut {
|
|
// Create a map with an initial capacity equal to the length of the input slice
|
|
resultMap := make(map[TKey]TOut, len(items))
|
|
|
|
// Iterate through each item in the slice
|
|
for _, item := range items {
|
|
// Get the key and value using the provided selectors
|
|
key := keySelector(item)
|
|
value := valueSelector(item)
|
|
|
|
// Store the key-value pair in the result map
|
|
resultMap[key] = value
|
|
}
|
|
|
|
return resultMap
|
|
}
|