From b79199f9be4a528101772801b28346cc174b35c7 Mon Sep 17 00:00:00 2001 From: kucherenkovova Date: Fri, 31 May 2024 20:28:08 +0300 Subject: [PATCH] [xslices] added `Unique` function (#3) --- go.work | 1 + xslices/README.md | 7 ++++++ xslices/go.mod | 3 +++ xslices/slices.go | 23 +++++++++++++++++++ xslices/slices_test.go | 52 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+) create mode 100644 xslices/README.md create mode 100644 xslices/go.mod create mode 100644 xslices/slices.go create mode 100644 xslices/slices_test.go diff --git a/go.work b/go.work index f56dbda..e035e45 100644 --- a/go.work +++ b/go.work @@ -4,6 +4,7 @@ use ( ./xmaps ./xmath ./xnet/xhttp + ./xslices ./xslog ./xstrconv ) diff --git a/xslices/README.md b/xslices/README.md new file mode 100644 index 0000000..ca59481 --- /dev/null +++ b/xslices/README.md @@ -0,0 +1,7 @@ +# xslices +Extensions to the standard Go library's `slices` package. + +### Install +``` +go get github.com/kucherenkovova/gopypaste/xslices@v0.1.0 +``` \ No newline at end of file diff --git a/xslices/go.mod b/xslices/go.mod new file mode 100644 index 0000000..e2fc147 --- /dev/null +++ b/xslices/go.mod @@ -0,0 +1,3 @@ +module github.com/kucherenkovova/gopypaste/xslices + +go 1.22 diff --git a/xslices/slices.go b/xslices/slices.go new file mode 100644 index 0000000..170d828 --- /dev/null +++ b/xslices/slices.go @@ -0,0 +1,23 @@ +package xslices + +// Unique returns a new slice containing only the unique elements of the input slice. +// Only first occurrence of each element is preserved. +func Unique[T comparable](list []T) []T { + if list == nil { + return nil + } + + seen := make(map[T]struct{}, len(list)) + results := make([]T, 0, len(list)) + + for _, element := range list { + if _, ok := seen[element]; ok { + continue + } + + seen[element] = struct{}{} + results = append(results, element) + } + + return results +} diff --git a/xslices/slices_test.go b/xslices/slices_test.go new file mode 100644 index 0000000..e62b489 --- /dev/null +++ b/xslices/slices_test.go @@ -0,0 +1,52 @@ +package xslices_test + +import ( + "reflect" + "testing" + + "github.com/kucherenkovova/gopypaste/xslices" +) + +func TestUnique(t *testing.T) { + type testCase struct { + name string + in []string + want []string + } + + tests := []testCase{ + { + name: "empty list", + in: []string{}, + want: []string{}, + }, + { + name: "nil", + in: nil, + want: nil, + }, + { + name: "no duplicates", + in: []string{"a", "b", "c"}, + want: []string{"a", "b", "c"}, + }, + { + name: "consequent duplicates", + in: []string{"a", "a", "b", "b", "c", "c"}, + want: []string{"a", "b", "c"}, + }, + { + name: "non-consequent duplicates", + in: []string{"a", "b", "a", "c", "b", "c"}, + want: []string{"a", "b", "c"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := xslices.Unique(tt.in); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Unique() = %v, want %v", got, tt.want) + } + }) + } +}