From 8c6f322a5abdaa892d4154efa8af980f3abedded Mon Sep 17 00:00:00 2001 From: alexchao26 Date: Mon, 21 Dec 2020 19:05:59 -0500 Subject: [PATCH] added slice splicing, intersection, remove algos --- data-structures/slice/slice.go | 93 +++++++++++++++++++++++++++++ data-structures/slice/slice_test.go | 64 ++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 data-structures/slice/slice.go create mode 100644 data-structures/slice/slice_test.go diff --git a/data-structures/slice/slice.go b/data-structures/slice/slice.go new file mode 100644 index 0000000..34f1a0f --- /dev/null +++ b/data-structures/slice/slice.go @@ -0,0 +1,93 @@ +package slice + +// DedupeStrings returns a new slice with duplicates removed, maintains original order +func DedupeStrings(sli []string) []string { + var result []string + seen := map[string]bool{} + for _, v := range sli { + if !seen[v] { + result = append(result, v) + seen[v] = true + } + } + return result +} + +// DedupeInts returns a new slice with duplicates removed, maintains original order +func DedupeInts(sli []int) []int { + var result []int + seen := map[int]bool{} + for _, v := range sli { + if !seen[v] { + result = append(result, v) + seen[v] = true + } + } + return result +} + +// IntersectionStrings returns a slice of values in both argument slices, deduped +func IntersectionStrings(sli1, sli2 []string) []string { + var result []string + seen := map[string]bool{} + for _, v := range sli1 { + seen[v] = true + } + for _, v := range sli2 { + if seen[v] { + result = append(result, v) + delete(seen, v) + } + } + return result +} + +// RemoveAllStrings returns a new slice with all instances of a given string removed +func RemoveAllStrings(sli []string, val string) []string { + var result []string + for _, v := range sli { + if v != val { + result = append(result, v) + } + } + return result +} + +// RemoveAllInts returns a new slice with all instances of a given int removed +func RemoveAllInts(sli []int, val int) []int { + var result []int + for _, v := range sli { + if v != val { + result = append(result, v) + } + } + return result +} + +// SpliceStrings removes a given number of elements starting at a given index +// if index + items >= len(sli) it does not throw an error +func SpliceStrings(sli []string, index int, items int) []string { + if items < 0 { + panic("cannot splice negative number of items") + } + if index+items >= len(sli) { + return sli[:index] + } + copy(sli[index:], sli[index+items:]) + sli = sli[:len(sli)-items] + return sli +} + +// SpliceInts removes a given number of elements starting at a given index +// if index + items >= len(sli) it does not throw an error +func SpliceInts(sli []int, index int, items int) []int { + if items < 0 { + panic("cannot splice negative number of items") + } + if index+items >= len(sli) { + return sli[:index] + } + copy(sli[index:], sli[index+items:]) + sli = sli[:len(sli)-items] + return sli +} diff --git a/data-structures/slice/slice_test.go b/data-structures/slice/slice_test.go new file mode 100644 index 0000000..b8de470 --- /dev/null +++ b/data-structures/slice/slice_test.go @@ -0,0 +1,64 @@ +package slice_test + +import ( + "reflect" + "testing" + + "github.com/alexchao26/advent-of-code-go/data-structures/slice" +) + +func TestDedupeStrings(t *testing.T) { + tests := []struct { + arg []string + want []string + }{ + {[]string{"abc", "def", "ghi", "jkl", "abc"}, []string{"abc", "def", "ghi", "jkl"}}, + {[]string{"A", "a"}, []string{"A", "a"}}, + {[]string{"A", "B", "B", "B"}, []string{"A", "B"}}, + } + for _, tt := range tests { + if got := slice.DedupeStrings(tt.arg); !reflect.DeepEqual(got, tt.want) { + t.Errorf("DedupeStrings() = %v, want %v", got, tt.want) + } + } +} +func TestIntersection(t *testing.T) { + tests := []struct { + arg1, arg2 []string + want []string + }{ + {[]string{"abc", "def", "ghi"}, []string{"jkl", "abc"}, []string{"abc"}}, + {[]string{"A", "a"}, []string{"A", "a"}, []string{"A", "a"}}, + {[]string{"A", "B", "C", "X"}, []string{"X", "p"}, []string{"X"}}, + } + for _, tt := range tests { + if got := slice.IntersectionStrings(tt.arg1, tt.arg2); !reflect.DeepEqual(got, tt.want) { + t.Errorf("DedupeStrings() = %v, want %v", got, tt.want) + } + } +} + +func TestSpliceString(t *testing.T) { + type args struct { + sli []string + index int + items int + } + tests := []struct { + name string + args args + want []string + }{ + {"example 1", args{[]string{"a", "b", "c", "d", "e"}, 4, 1}, []string{"a", "b", "c", "d"}}, + {"example 2", args{[]string{"a", "b", "c", "d", "e"}, 4, 2}, []string{"a", "b", "c", "d"}}, + {"example 3", args{[]string{"a", "b", "c", "d", "e"}, 3, 2}, []string{"a", "b", "c"}}, + {"example 4", args{[]string{"a", "b", "c", "d", "e"}, 0, 2}, []string{"c", "d", "e"}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := slice.SpliceStrings(tt.args.sli, tt.args.index, tt.args.items); !reflect.DeepEqual(got, tt.want) { + t.Errorf("SpliceString() = %v, want %v", got, tt.want) + } + }) + } +}