Skip to content

Commit

Permalink
feat: moved code from slices to slice
Browse files Browse the repository at this point in the history
  • Loading branch information
trakhimenok committed Aug 14, 2024
1 parent da02730 commit ac6700f
Show file tree
Hide file tree
Showing 13 changed files with 430 additions and 33 deletions.
11 changes: 0 additions & 11 deletions contains.go

This file was deleted.

21 changes: 0 additions & 21 deletions contains_test.go

This file was deleted.

74 changes: 74 additions & 0 deletions csv_non_unique.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package slice

import (
"bytes"
"strings"
)

type CommaSeparatedValuesList string

func (csv CommaSeparatedValuesList) Add(v string) CommaSeparatedValuesList {
if strings.Contains(v, ",") {
panic("contains comma")
}
if csv == "" {
return CommaSeparatedValuesList(v)
}
return CommaSeparatedValuesList(string(csv) + "," + v)
}

func (csv CommaSeparatedValuesList) Count() int {
if csv == "" {
return 0
}
return strings.Count(string(csv), ",") + 1
}

func (csv CommaSeparatedValuesList) Set(i int, v string) CommaSeparatedValuesList {
vals := strings.Split(string(csv), ",")
if i >= len(vals) {
panic("out of range")
}
vals[i] = v
return CommaSeparatedValuesList(strings.Join(vals, ","))
}

func (csv CommaSeparatedValuesList) Contains(v string) bool {
s := string(csv)
vLen := len(v)
return (strings.HasPrefix(s, v) && (len(s) == vLen || s[vLen:vLen+1] == ",")) ||
strings.HasSuffix(s, ","+v) || strings.Contains(s, ","+v+",")
}

func (csv CommaSeparatedValuesList) Remove(v string) CommaSeparatedValuesList {
return CommaSeparatedValuesList(removeValFromCSV(string(csv), v))
}

func (csv CommaSeparatedValuesList) Strings() []string {
if csv == "" {
return []string{}
}
return strings.Split(string(csv), ",")
}

func (csv CommaSeparatedValuesList) String() string {
return string(csv)
}

func removeValFromCSV(s, v string) string {
if len(s) == 0 {
return s
}
var buf bytes.Buffer
vals := strings.Split(s, ",")
for _, val := range vals {
if val != v {
buf.WriteString(val)
buf.WriteString(",")
}
}
if buf.Len() > 0 {
buf.Truncate(buf.Len() - 1)
}
return buf.String()
}
73 changes: 73 additions & 0 deletions csv_non_unique_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package slice

import (
"testing"
)

func TestCommaSeparatedValuesList_Add(t *testing.T) {
var csvl CommaSeparatedValuesList
if csvl = csvl.Add("v1"); csvl != "v1" {
t.Error("unexpected: " + csvl)
}
if csvl = csvl.Add("v3"); csvl != "v1,v3" {
t.Error("unexpected")
}
if csvl = csvl.Add("v2"); csvl != "v1,v3,v2" {
t.Error("unexpected")
}
}
func TestCommaSeparatedValuesList_Remove(t *testing.T) {
var csvl CommaSeparatedValuesList
csvl = CommaSeparatedValuesList("")
if csvl = csvl.Remove("v1"); csvl != "" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedValuesList("v1")
if csvl = csvl.Remove("v1"); csvl != "" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedValuesList("v2")
if csvl = csvl.Remove("v1"); csvl != "v2" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v1"); csvl != "v3,v2,v4" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v2"); csvl != "v1,v3,v4" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v3"); csvl != "v1,v2,v4" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v4"); csvl != "v1,v3,v2" {
t.Error("unexpected: " + csvl)
}
}

func TestCommaSeparatedValuesList_Contains(t *testing.T) {
if CommaSeparatedValuesList("").Contains("v1") {
t.Error("unexpected true")
}
if !CommaSeparatedValuesList("v1").Contains("v1") {
t.Error("unexpected false")
}
if !CommaSeparatedValuesList("v1,v2").Contains("v1") {
t.Error("unexpected false")
}
if !CommaSeparatedValuesList("v1,v2").Contains("v2") {
t.Error("unexpected false")
}
if !CommaSeparatedValuesList("v1,v2,v3").Contains("v1") {
t.Error("unexpected false")
}
if !CommaSeparatedValuesList("v1,v2,v3").Contains("v2") {
t.Error("unexpected false")
}
if !CommaSeparatedValuesList("v1,v2,v3").Contains("v3") {
t.Error("unexpected false")
}
}
48 changes: 48 additions & 0 deletions csv_unique.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package slice

import (
"strings"
)

type CommaSeparatedUniqueValuesList string

func (csv CommaSeparatedUniqueValuesList) Add(v string, limit int) CommaSeparatedUniqueValuesList {
if strings.Contains(v, ",") {
panic("contains comma")
}
if csv == "" {
return CommaSeparatedUniqueValuesList(v)
}
vals := strings.Split(string(csv), ",")
for _, val := range vals {
if val == v {
return csv
}
}
if limit > 0 && len(vals) > limit {
vals = vals[:limit]
}
return CommaSeparatedUniqueValuesList(strings.Join(append(vals, v), ","))
}

func (csv CommaSeparatedUniqueValuesList) Contains(v string) bool {
s := string(csv)
vLen := len(v)
return (strings.HasPrefix(s, v) && (len(s) == vLen || s[vLen:vLen+1] == ",")) ||
strings.HasSuffix(s, ","+v) || strings.Contains(s, ","+v+",")
}

func (csv CommaSeparatedUniqueValuesList) Remove(v string) CommaSeparatedUniqueValuesList {
return CommaSeparatedUniqueValuesList(removeValFromCSV(string(csv), v))
}

func (csv CommaSeparatedUniqueValuesList) Strings() []string {
if csv == "" {
return []string{}
}
return strings.Split(string(csv), ",")
}

func (csv CommaSeparatedUniqueValuesList) String() string {
return string(csv)
}
73 changes: 73 additions & 0 deletions csv_unique_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package slice

import (
"testing"
)

func TestCommaSeparatedUniqueValuesList_Add(t *testing.T) {
var csvl CommaSeparatedUniqueValuesList
if csvl = csvl.Add("v1", 0); csvl != "v1" {
t.Error("unexpected: " + csvl)
}
if csvl = csvl.Add("v3", 0); csvl != "v1,v3" {
t.Error("unexpected")
}
if csvl = csvl.Add("v2", 0); csvl != "v1,v3,v2" {
t.Error("unexpected")
}
}
func TestCommaSeparatedUniqueValuesList_Remove(t *testing.T) {
var csvl CommaSeparatedUniqueValuesList
csvl = CommaSeparatedUniqueValuesList("")
if csvl = csvl.Remove("v1"); csvl != "" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedUniqueValuesList("v1")
if csvl = csvl.Remove("v1"); csvl != "" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedUniqueValuesList("v2")
if csvl = csvl.Remove("v1"); csvl != "v2" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedUniqueValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v1"); csvl != "v3,v2,v4" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedUniqueValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v2"); csvl != "v1,v3,v4" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedUniqueValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v3"); csvl != "v1,v2,v4" {
t.Error("unexpected: " + csvl)
}
csvl = CommaSeparatedUniqueValuesList("v1,v3,v2,v4")
if csvl = csvl.Remove("v4"); csvl != "v1,v3,v2" {
t.Error("unexpected: " + csvl)
}
}

func TestCommaSeparatedUniqueValuesList_Contains(t *testing.T) {
if CommaSeparatedUniqueValuesList("").Contains("v1") {
t.Error("unexpected true")
}
if !CommaSeparatedUniqueValuesList("v1").Contains("v1") {
t.Error("unexpected false")
}
if !CommaSeparatedUniqueValuesList("v1,v2").Contains("v1") {
t.Error("unexpected false")
}
if !CommaSeparatedUniqueValuesList("v1,v2").Contains("v2") {
t.Error("unexpected false")
}
if !CommaSeparatedUniqueValuesList("v1,v2,v3").Contains("v1") {
t.Error("unexpected false")
}
if !CommaSeparatedUniqueValuesList("v1,v2,v3").Contains("v2") {
t.Error("unexpected false")
}
if !CommaSeparatedUniqueValuesList("v1,v2,v3").Contains("v3") {
t.Error("unexpected false")
}
}
18 changes: 18 additions & 0 deletions merge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package slice

func Merge[T comparable](source []T, slices ...[]T) (result []T, changed bool) {
result = source[:]
for _, slice := range slices {
for _, v := range slice {
for _, r := range result {
if r == v {
goto found
}
}
result = append(result, v)
changed = true
found:
}
}
return
}
31 changes: 31 additions & 0 deletions merge_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package slice

import "testing"

func TestMerge(t *testing.T) {
source := []string{"a", "b", "c"}
slice1 := []string{"b", "c", "d"}
slice2 := []string{"c", "d", "e"}
result, changed := Merge(source, slice1, slice2)
if !changed {
t.Error("Expected changed to be true")
}
if len(result) != 5 {
t.Errorf("Expected 5 values in result, got: %d", len(result))
}
if result[0] != "a" {
t.Errorf("First value should be a, got: %v", result[0])
}
if result[1] != "b" {
t.Errorf("Second value should be b, got: %v", result[1])
}
if result[2] != "c" {
t.Errorf("Third value should be c, got: %v", result[2])
}
if result[3] != "d" {
t.Errorf("Fourth value should be d, got: %v", result[3])
}
if result[4] != "e" {
t.Errorf("Fifth value should be e, got: %v", result[4])
}
}
16 changes: 16 additions & 0 deletions remove_multi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package slice

func RemoveMulti[T comparable](source, remove []T) (result []T, removedCount int) {
result = source[:0]
sourceRange:
for _, s := range source {
for _, r := range remove {
if s == r {
removedCount++
continue sourceRange
}
}
result = append(result, s)
}
return
}
Loading

0 comments on commit ac6700f

Please sign in to comment.