Have StringSet preserve original order of values
This commit is contained in:
parent
8552cacf79
commit
a4a41c23e6
2 changed files with 56 additions and 6 deletions
|
|
@ -3,6 +3,7 @@ package set
|
|||
var exists = struct{}{}
|
||||
|
||||
type stringSet struct {
|
||||
v []string
|
||||
m map[string]struct{}
|
||||
}
|
||||
|
||||
|
|
@ -13,7 +14,11 @@ func NewStringSet() *stringSet {
|
|||
}
|
||||
|
||||
func (s *stringSet) Add(value string) {
|
||||
if s.Contains(value) {
|
||||
return
|
||||
}
|
||||
s.m[value] = exists
|
||||
s.v = append(s.v, value)
|
||||
}
|
||||
|
||||
func (s *stringSet) AddValues(values []string) {
|
||||
|
|
@ -23,7 +28,25 @@ func (s *stringSet) AddValues(values []string) {
|
|||
}
|
||||
|
||||
func (s *stringSet) Remove(value string) {
|
||||
if !s.Contains(value) {
|
||||
return
|
||||
}
|
||||
delete(s.m, value)
|
||||
s.v = sliceWithout(s.v, value)
|
||||
}
|
||||
|
||||
func sliceWithout(s []string, v string) []string {
|
||||
idx := -1
|
||||
for i, item := range s {
|
||||
if item == v {
|
||||
idx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if idx < 0 {
|
||||
return s
|
||||
}
|
||||
return append(s[:idx], s[idx+1:]...)
|
||||
}
|
||||
|
||||
func (s *stringSet) RemoveValues(values []string) {
|
||||
|
|
@ -37,10 +60,10 @@ func (s *stringSet) Contains(value string) bool {
|
|||
return c
|
||||
}
|
||||
|
||||
func (s *stringSet) ToSlice() []string {
|
||||
r := make([]string, 0, len(s.m))
|
||||
for k := range s.m {
|
||||
r = append(r, k)
|
||||
}
|
||||
return r
|
||||
func (s *stringSet) Len() int {
|
||||
return len(s.m)
|
||||
}
|
||||
|
||||
func (s *stringSet) ToSlice() []string {
|
||||
return s.v
|
||||
}
|
||||
|
|
|
|||
27
pkg/set/string_set_test.go
Normal file
27
pkg/set/string_set_test.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package set
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_StringSlice_ToSlice(t *testing.T) {
|
||||
s := NewStringSet()
|
||||
s.Add("one")
|
||||
s.Add("two")
|
||||
s.Add("three")
|
||||
s.Add("two")
|
||||
assert.Equal(t, []string{"one", "two", "three"}, s.ToSlice())
|
||||
}
|
||||
|
||||
func Test_StringSlice_Remove(t *testing.T) {
|
||||
s := NewStringSet()
|
||||
s.Add("one")
|
||||
s.Add("two")
|
||||
s.Add("three")
|
||||
s.Remove("two")
|
||||
assert.Equal(t, []string{"one", "three"}, s.ToSlice())
|
||||
assert.False(t, s.Contains("two"))
|
||||
assert.Equal(t, 2, s.Len())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue