Files
base/pkg/array/map.go
2026-04-10 18:25:21 +03:30

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
}