From 688922957ad1033ca14333bc82f3594ca9b9b097 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 28 Aug 2024 09:38:48 -0500 Subject: [PATCH] chore: implement unique function for slices --- coderd/util/slice/example_test.go | 4 ++-- coderd/util/slice/slice.go | 20 ++++++++++++++++++-- coderd/util/slice/slice_test.go | 27 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/coderd/util/slice/example_test.go b/coderd/util/slice/example_test.go index f17d9c4aab0ff..fd0addb1c87fd 100644 --- a/coderd/util/slice/example_test.go +++ b/coderd/util/slice/example_test.go @@ -10,8 +10,8 @@ import ( func ExampleSymmetricDifference() { // The goal of this function is to find the elements to add & remove from // set 'a' to make it equal to set 'b'. - a := []int{1, 2, 5, 6} - b := []int{2, 3, 4, 5} + a := []int{1, 2, 5, 6, 6, 6} + b := []int{2, 3, 3, 3, 4, 5} add, remove := slice.SymmetricDifference(a, b) fmt.Println("Elements to add:", add) fmt.Println("Elements to remove:", remove) diff --git a/coderd/util/slice/slice.go b/coderd/util/slice/slice.go index e186e0975de70..78d5e7fe61928 100644 --- a/coderd/util/slice/slice.go +++ b/coderd/util/slice/slice.go @@ -62,6 +62,20 @@ func Overlap[T comparable](a []T, b []T) bool { }) } +func UniqueFunc[T any](a []T, equal func(a, b T) bool) []T { + cpy := make([]T, 0, len(a)) + + for _, v := range a { + if ContainsCompare(cpy, v, equal) { + continue + } + + cpy = append(cpy, v) + } + + return cpy +} + // Unique returns a new slice with all duplicate elements removed. func Unique[T comparable](a []T) []T { cpy := make([]T, 0, len(a)) @@ -109,7 +123,7 @@ func Descending[T constraints.Ordered](a, b T) int { } // SymmetricDifference returns the elements that need to be added and removed -// to get from set 'a' to set 'b'. +// to get from set 'a' to set 'b'. Note that duplicates are ignored in sets. // In classical set theory notation, SymmetricDifference returns // all elements of {add} and {remove} together. It is more useful to // return them as their own slices. @@ -117,7 +131,7 @@ func Descending[T constraints.Ordered](a, b T) int { // Example: // // a := []int{1, 3, 4} -// b := []int{1, 2} +// b := []int{1, 2, 2, 2} // add, remove := SymmetricDifference(a, b) // fmt.Println(add) // [2] // fmt.Println(remove) // [3, 4] @@ -127,6 +141,8 @@ func SymmetricDifference[T comparable](a, b []T) (add []T, remove []T) { } func SymmetricDifferenceFunc[T any](a, b []T, equal func(a, b T) bool) (add []T, remove []T) { + // Ignore all duplicates + a, b = UniqueFunc(a, equal), UniqueFunc(b, equal) return DifferenceFunc(b, a, equal), DifferenceFunc(a, b, equal) } diff --git a/coderd/util/slice/slice_test.go b/coderd/util/slice/slice_test.go index 5ab61f83ddbc1..df8d119273652 100644 --- a/coderd/util/slice/slice_test.go +++ b/coderd/util/slice/slice_test.go @@ -52,6 +52,22 @@ func TestUnique(t *testing.T) { slice.Unique([]string{ "a", "a", "a", })) + + require.ElementsMatch(t, + []int{1, 2, 3, 4, 5}, + slice.UniqueFunc([]int{ + 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, + }, func(a, b int) bool { + return a == b + })) + + require.ElementsMatch(t, + []string{"a"}, + slice.UniqueFunc([]string{ + "a", "a", "a", + }, func(a, b string) bool { + return a == b + })) } func TestContains(t *testing.T) { @@ -230,4 +246,15 @@ func TestSymmetricDifference(t *testing.T) { require.ElementsMatch(t, []int{1, 2, 3}, add) require.ElementsMatch(t, []int{}, remove) }) + + t.Run("Duplicates", func(t *testing.T) { + t.Parallel() + + add, remove := slice.SymmetricDifference( + []int{5, 5, 5, 1, 1, 1, 3, 3, 3, 5, 5, 5}, + []int{2, 2, 2, 1, 1, 1, 2, 4, 4, 4, 5, 5, 5, 1, 1}, + ) + require.ElementsMatch(t, []int{2, 4}, add) + require.ElementsMatch(t, []int{3}, remove) + }) } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy