diff --git a/pkg/collections/utils.go b/pkg/collections/utils.go index 3c2c1dc..0690c49 100644 --- a/pkg/collections/utils.go +++ b/pkg/collections/utils.go @@ -1,10 +1,20 @@ package collections -// ProjectSlice takes a slice and a projection function and applies this function to each element of the slice. +// ProjectSliceToSlice takes a slice and a projection function and applies this function to each element of the slice. // It returns a new slice containing the results of the projection. // The original slice is not modified. // If the projection function is nil, it returns nil. +// +// Deprecated: With the introduction of ProjectSliceToMap, this function has been replaced by ProjectSliceToSlice for better naming consistency. func ProjectSlice[X any, Y any](src []X, project func(X) Y) []Y { + return ProjectSliceToSlice(src, project) +} + +// ProjectSliceToSlice takes a slice and a projection function and applies this function to each element of the slice. +// It returns a new slice containing the results of the projection. +// The original slice is not modified. +// If the projection function is nil, it returns nil. +func ProjectSliceToSlice[X any, Y any](src []X, project func(X) Y) []Y { if project == nil { return nil } @@ -15,6 +25,23 @@ func ProjectSlice[X any, Y any](src []X, project func(X) Y) []Y { return res } +// ProjectSliceToMap takes a slice and a projection function and applies this function to each element of the slice. +// It returns a new map containing the results of the projection. +// The original slice is not modified. +// Note that the resulting map may be smaller if the projection function does not guarantee unique keys. +// If the projection function is nil, it returns nil. +func ProjectSliceToMap[X any, K comparable, V any](src []X, project func(X) (K, V)) map[K]V { + if project == nil { + return nil + } + res := make(map[K]V, len(src)) + for _, x := range src { + k, v := project(x) + res[k] = v + } + return res +} + // ProjectMapToSlice takes a map and a projection function and applies this function to each key-value pair in the map. // It returns a new slice containing the results of the projection. // The original map is not modified. diff --git a/pkg/collections/utils_test.go b/pkg/collections/utils_test.go index 9d2e61d..f796409 100644 --- a/pkg/collections/utils_test.go +++ b/pkg/collections/utils_test.go @@ -12,7 +12,7 @@ import ( var _ = Describe("Utils Tests", func() { - Context("ProjectSlice", func() { + Context("ProjectSliceToSlice", func() { projectFunc := func(i int) int { return i * 2 @@ -20,19 +20,46 @@ var _ = Describe("Utils Tests", func() { It("should use the projection function on each element of the slice", func() { src := []int{1, 2, 3, 4} - projected := collections.ProjectSlice(src, projectFunc) + projected := collections.ProjectSliceToSlice(src, projectFunc) Expect(projected).To(Equal([]int{2, 4, 6, 8})) Expect(src).To(Equal([]int{1, 2, 3, 4}), "original slice should not be modified") }) It("should return an empty slice for an empty or nil input slice", func() { - Expect(collections.ProjectSlice(nil, projectFunc)).To(BeEmpty()) - Expect(collections.ProjectSlice([]int{}, projectFunc)).To(BeEmpty()) + Expect(collections.ProjectSliceToSlice(nil, projectFunc)).To(BeEmpty()) + Expect(collections.ProjectSliceToSlice([]int{}, projectFunc)).To(BeEmpty()) }) It("should return nil for a nil projection function", func() { src := []int{1, 2, 3, 4} - projected := collections.ProjectSlice[int, int](src, nil) + projected := collections.ProjectSliceToSlice[int, int](src, nil) + Expect(projected).To(BeNil()) + Expect(src).To(Equal([]int{1, 2, 3, 4}), "original slice should not be modified") + }) + + }) + + Context("ProjectSliceToMap", func() { + + projectFunc := func(i int) (int, int) { + return i, i * 2 + } + + It("should use the projection function on each element of the slice", func() { + src := []int{1, 2, 3, 4} + projected := collections.ProjectSliceToMap(src, projectFunc) + Expect(projected).To(Equal(map[int]int{1: 2, 2: 4, 3: 6, 4: 8})) + Expect(src).To(Equal([]int{1, 2, 3, 4}), "original slice should not be modified") + }) + + It("should return an empty slice for an empty or nil input slice", func() { + Expect(collections.ProjectSliceToMap(nil, projectFunc)).To(BeEmpty()) + Expect(collections.ProjectSliceToMap([]int{}, projectFunc)).To(BeEmpty()) + }) + + It("should return nil for a nil projection function", func() { + src := []int{1, 2, 3, 4} + projected := collections.ProjectSliceToMap[int, int, int](src, nil) Expect(projected).To(BeNil()) Expect(src).To(Equal([]int{1, 2, 3, 4}), "original slice should not be modified") }) diff --git a/pkg/conditions/updater.go b/pkg/conditions/updater.go index fc47495..dffe6d3 100644 --- a/pkg/conditions/updater.go +++ b/pkg/conditions/updater.go @@ -133,7 +133,7 @@ func (c *conditionUpdater) RemoveCondition(conType string) *conditionUpdater { // The conditions are returned sorted by their type. // The second return value indicates whether the condition list has actually changed. func (c *conditionUpdater) Conditions() ([]metav1.Condition, bool) { - res := collections.ProjectSlice(c.updatedConditions(), func(con metav1.Condition) metav1.Condition { + res := collections.ProjectSliceToSlice(c.updatedConditions(), func(con metav1.Condition) metav1.Condition { if c.original[con.Type].Status == con.Status { // if the status has not changed, reset the LastTransitionTime to the original value con.LastTransitionTime = c.original[con.Type].LastTransitionTime