Skip to content

Commit

Permalink
Merge pull request #1 from oze4/add-splice
Browse files Browse the repository at this point in the history
Add Splice function
  • Loading branch information
matthewoestreich authored Aug 14, 2024
2 parents 2d1f356 + 5cdecc5 commit 4761416
Show file tree
Hide file tree
Showing 3 changed files with 270 additions and 4 deletions.
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,81 @@ r := jslice.Slice(s, start, end)
// r == []int{1,2,3}
```

## Splice

Changes the contents of a slice by removing or replacing existing elements and/or adding new elements.

- If `deleteCount` and `replacementElements` both equal `0`, we just return the original slice without modifying anything.
- If `start` is greater than or equal to the length of the slice, no elements will be deleted, but the method will behave as an adding function.

<b>Remove `0` elements before index `2` and insert "`earth`" and "`mars`"</b>
```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
jslice.Splice(&s, 2, 0, "earth", "mars")
// s == []string{"mercury", "venus", "earth", "mars", "jupiter", "saturn"}
```

**Remove `0` elements at index `0` and insert "`earth`" and "`mars`".**

```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
jslice.Splice(&s, 0, 0, "earth", "mars")
// s == []string{"earth", "mars", "mercury", "venus", "jupiter", "saturn"}
```

**Remove `1` element at index `2`, and insert "`earth`" and "`mars`"**

```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
jslice.Splice(&s, 2, 1, "earth", "mars")
// s == []string{"mercury", "venus", "earth", "mars", "saturn"}
```

**Remove `1` element at index `0` and insert "`earth`" and "`mars`"**

```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
jslice.Splice(&s, 0, 1, "earth", "mars")
// s == []string{"earth", "mars", "venus", "jupiter", "saturn"}
```

**Remove `3` elements starting at index `1` and insert nothing**

```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
jslice.Splice(&s, 1, 3)
// s == []string{"mercury"}
```

**If `start` + `deleteCount` is greater than or equal to slice length, we modify `deleteCount` to equal the length of the slice - `start`**

```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
jslice.Splice(&s, 2, 100) // <- 100 greater than slice length
// s == []string{"mercury", "venus"}
```

**If `start` is greater than or equal to the length of the slice, no elements are removed, but the method is treated as an add function**

```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
// Even though `deleteCount` == 1, nothing will be
// deleted because `start` >= length of slice.
jslice.Splice(&s, 100, 1, "earth", "mars")
// s == []string{"mercury", "venus", "jupiter", "saturn", "earth", "mars"}
```

**Splice last element by removing `1` element at index `3` and inserting "`earth`" and "`mars`"**

```go
s := []string{"mercury", "venus", "jupiter", "saturn"}
jslice.Splice(&s, 3, 1, "earth", "mars")
// s == []string{"mercury", "venus", "jupiter", "earth", "mars"}
```




<br />
<br />
<br />
Expand Down
170 changes: 166 additions & 4 deletions jslice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func TestEvery(t *testing.T) {

func TestSlice(t *testing.T) {
const (
EXPECT_OG_LEN = 5
EXPECT_OG_LEN = 5
EXPECT_SLICED_LEN = 3
)
s := []int{1, 2, 3, 4, 5}
Expand All @@ -177,21 +177,183 @@ func TestSlice(t *testing.T) {

func TestShift(t *testing.T) {
const (
EXPECT_OG_LEN = 3
EXPECT_OG_LEN = 3
EXPECT_RESULT_VAL = 1
)
s := []int{1,2,3,4}
s := []int{1, 2, 3, 4}
r := jslice.Shift(&s)
if len(s) != EXPECT_OG_LEN {
t.Fatalf("Expected original slice length to now be = %d | Got = %d\n", EXPECT_OG_LEN, len(s))
}
if (r != EXPECT_RESULT_VAL) {
if r != EXPECT_RESULT_VAL {
t.Fatalf("Expected result value to be = %d | Got = %d\n", EXPECT_RESULT_VAL, r)
}
t.Log(s)
t.Log(r)
}

func TestSplice_StartIndex2_Delete0_Insert2(t *testing.T) {
EXPECT := []string{"mercury", "venus", "earth", "mars", "jupiter", "saturn"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 2, 0, "earth", "mars")

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_StartIndex0_Delete0_Insert2(t *testing.T) {
EXPECT := []string{"earth", "mars", "mercury", "venus", "jupiter", "saturn"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 0, 0, "earth", "mars")

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_StartIndex2_Delete1_Insert2(t *testing.T) {
EXPECT := []string{"mercury", "venus", "earth", "mars", "saturn"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 2, 1, "earth", "mars")

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_StartIndex0_Delete1_Insert2(t *testing.T) {
EXPECT := []string{"earth", "mars", "venus", "jupiter", "saturn"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 0, 1, "earth", "mars")

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_StartIndex1_DeleteCount0_Insert0(t *testing.T) {
EXPECT := []string{"mercury"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 1, 3)

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_DeleteCountGreaterThanSliceLen(t *testing.T) {
EXPECT := []string{"mercury", "venus"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 2, 100)

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_StartIndexGreaterThanSliceLen_WithoutReplacementItems(t *testing.T) {
EXPECT := []string{"mercury", "venus", "jupiter", "saturn"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 100, 100)

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_StartIndexGreaterThanSliceLen_WithReplacementItems(t *testing.T) {
EXPECT := []string{"mercury", "venus", "jupiter", "saturn", "earth", "mars"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 100, 1, "earth", "mars")

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

func TestSplice_SpliceLastElement(t *testing.T) {
EXPECT := []string{"mercury", "venus", "jupiter", "earth", "mars"}
s := []string{"mercury", "venus", "jupiter", "saturn"}

jslice.Splice(&s, 3, 1, "earth", "mars")

if len(EXPECT) != len(s) {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
// use jslice to help with testing ;)
jslice.ForEach(s, func(i int, e string) {
if EXPECT[i] != e {
t.Fatalf("\nExpected\t= %v\nGot\t\t= %v\n", EXPECT, s)
}
})
t.Log(s)
}

// **************************************************************

func TestTest(t *testing.T) {
Expand Down
29 changes: 29 additions & 0 deletions splice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package jslice

// Splice changes the contents of a slice by removing or replacing existing elements,
// and/or adding new elements.
func Splice[T any](s *[]T, start uint, deleteCount uint, replacementItems ...T) {
if deleteCount == 0 && len(replacementItems) == 0 {
return //*s
}

// If start >= len(*s) no elements will be deleted, but the method will behave as
// an adding function.
if start >= uint(len(*s)) {
if len(replacementItems) == 0 {
return //*s
}
*s = append(*s, replacementItems...)
return //*s
}

// If the "end" (start+deleteCount) is greater than the length of the slice, limit
// the delete count to the length of the slice - start. Otherwise we get index out
// of bounds error.
if start + deleteCount >= uint(len(*s)) {
deleteCount = uint(len(*s)) - start
}

*s = append((*s)[0:start], append(replacementItems, (*s)[start+deleteCount:]...)...)
return //*s
}

0 comments on commit 4761416

Please sign in to comment.