Skip to content

Commit

Permalink
slice: add some Slice functions
Browse files Browse the repository at this point in the history
    - SliceContentCmp
    - SliceDedupe

Signed-off-by: Vicente Cheng <vicente.cheng@suse.com>
  • Loading branch information
Vicente-Cheng committed Dec 14, 2023
1 parent 8d42a1e commit 3e3f7fd
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/godbus/dbus/v5 v5.0.4
github.com/sirupsen/logrus v1.9.2
github.com/stretchr/testify v1.7.0
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8=
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
45 changes: 45 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package gocommon

import "golang.org/x/exp/slices"

// SliceContentCmp compares two slices and returns true if they have the same content with any order.
func SliceContentCmp[T comparable](x, y []T) bool {
if len(x) == 0 && len(y) == 0 {
return true
}
if len(x) != len(y) {
return false
}

yMap := make(map[T]int, len(y))
for _, item := range y {
yMap[item]++
}

for _, xItem := range x {
if counter, exist := yMap[xItem]; exist {
if counter == 0 {
return false
}
yMap[xItem]--
} else {
return false
}
}
return true
}

// SliceDedupe removes duplicated items and return a non-deplucated items slice.
func SliceDedupe[T comparable](x []T) []T {
if len(x) == 0 {
return x
}

result := make([]T, 0)
for _, item := range x {
if !slices.Contains(result, item) {
result = append(result, item)
}
}
return result
}
79 changes: 79 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package gocommon

import (
"testing"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)

type SliceFuncs struct {
suite.Suite
}

func TestSliceFuncs(t *testing.T) {
suite.Run(t, new(SliceFuncs))
}

func (s *SliceFuncs) SetupSuite() {
// you could do something here before all tests
}

func (s *SliceFuncs) TestSliceContentCmpInt() {
a := []int{1, 1, 2, 3}
b := []int{3, 2, 1, 1}
c := []int{1, 2, 3, 4}
d := []int{}
e := []int{}
f := []int{1, 1, 2}
g := []int{1, 2, 2}
fCpy := []int{1, 1, 2}
gCpy := []int{1, 2, 2}

s.Equal(true, SliceContentCmp(a, b), "SliceContentCmp should return true")
s.Equal(false, SliceContentCmp(a, c), "SliceContentCmp should return false")
s.Equal(true, SliceContentCmp(d, e), "SliceContentCmp should return true")
s.Equal(false, SliceContentCmp(f, g), "SliceContentCmp should return false")
s.Equal(f, fCpy, "original slice should not change.")
s.Equal(g, gCpy, "original slice should not change.")

}

func (s *SliceFuncs) TestSliceContentCmpString() {
a := []string{"a", "b", "c"}
b := []string{"b", "c", "a"}
c := []string{"a", "b", "c", "d"}
d := []string{}
e := []string{}
f := []string{"a", "a", "b"}
g := []string{"a", "b", "b"}
fCpy := []string{"a", "a", "b"}
gCpy := []string{"a", "b", "b"}

s.Equal(true, SliceContentCmp(a, b), "SliceContentCmp should return true")
s.Equal(false, SliceContentCmp(a, c), "SliceContentCmp should return false")
s.Equal(true, SliceContentCmp(d, e), "SliceContentCmp should return true")
s.Equal(false, SliceContentCmp(f, g), "SliceContentCmp should return false")
s.Equal(f, fCpy, "original slice should not change.")
s.Equal(g, gCpy, "original slice should not change.")
}

func (s *SliceFuncs) TestSliceDedupeInt() {
a := []int{1, 1, 2, 2, 3, 3}
b := []int{1, 2, 3, 4, 5, 6}
c := []int{1, 2, 3, 3, 4}

require.Equal(s.T(), []int{1, 2, 3}, SliceDedupe(a), "SliceDedupe should return the same slice with {1, 2, 3}")
require.Equal(s.T(), []int{1, 2, 3, 4, 5, 6}, SliceDedupe(b), "SliceDedupe should return the same slice with {1, 2, 3, 4, 5, 6}")
require.Equal(s.T(), []int{1, 2, 3, 4}, SliceDedupe(c), "SliceDedupe should return the same slice with {1, 2, 3, 4}")
}

func (s *SliceFuncs) TestSliceDedupeString() {
a := []string{"foo", "bar", "bar", "foo", "roll", "roll"}
b := []string{"apple", "book", "clock", "duck", "escape", "field"}
c := []string{"foo", "bar", "roll", "roll", "desk"}

require.Equal(s.T(), []string{"foo", "bar", "roll"}, SliceDedupe(a), "SliceDedupe should return the same slice with {foo, bar, roll}")
require.Equal(s.T(), []string{"apple", "book", "clock", "duck", "escape", "field"}, SliceDedupe(b), "SliceDedupe should return the same slice with {apple, book, clock, duck, escape, field}")
require.Equal(s.T(), []string{"foo", "bar", "roll", "desk"}, SliceDedupe(c), "SliceDedupe should return the same slice with {foo, bar, roll, desk}")
}

0 comments on commit 3e3f7fd

Please sign in to comment.