diff --git a/src/slices/slices.go b/src/slices/slices.go index 326584064c0c1c..b884d89aab00c2 100644 --- a/src/slices/slices.go +++ b/src/slices/slices.go @@ -474,3 +474,12 @@ func Concat[S ~[]E, E any](slices ...S) S { } return newslice } + +// Map returns a new slice containing the result of applying fn to each element of s. +func Map[S ~[]E, E, R any](s S, fn func(E) R) []R { + var result []R + for _, item := range s { + result = append(result, fn(item)) + } + return result +} diff --git a/src/slices/slices_test.go b/src/slices/slices_test.go index 4b5f0355df2af7..fdc8e2299f55a3 100644 --- a/src/slices/slices_test.go +++ b/src/slices/slices_test.go @@ -10,6 +10,7 @@ import ( "internal/testenv" "math" . "slices" + "strconv" "strings" "testing" ) @@ -1335,3 +1336,29 @@ func TestConcat_too_large(t *testing.T) { } } } + +func TestMap(t *testing.T) { + s1 := []int{1, 2, 3, 4, 5} + got1 := Map(s1, func(n int) int { return n * 2 }) + want1 := []int{2, 4, 6, 8, 10} + if !Equal(want1, got1) { + t.Errorf("Map(%v) = %v, want %v", s1, got1, want1) + } + + s2 := []int{1, 2, 3, 4, 5} + got2 := Map(s2, strconv.Itoa) + want2 := []string{"1", "2", "3", "4", "5"} + if !Equal(want2, got2) { + t.Errorf("Map(%v) = %v, want %v", s2, got2, want2) + } + + s3 := []string{"1", "2", "3", "4", "5"} + type T struct { + A string + } + got3 := Map(s3, func(s string) T { return T{s} }) + want3 := []T{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}} + if !Equal(want3, got3) { + t.Errorf("Map(%v) = %v, want %v", s3, got3, want3) + } +}