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 }