Skip to content

Commit

Permalink
Add slice Splice an element or multiple elements at index i. (#371)
Browse files Browse the repository at this point in the history
* Add slice Splice an element or multiple elements at index i.

* Update README.md

* Update slice.go

* Update slice.go

* Update README.md

* Update slice_test.go

---------

Co-authored-by: wenlingang <lingang.wen@longbridge.sg>
Co-authored-by: Samuel Berthe <dev@samuel-berthe.fr>
  • Loading branch information
3 people authored Jun 29, 2024
1 parent 42a90a0 commit fe16ff7
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Supported helpers for slices:
- [Compact](#compact)
- [IsSorted](#issorted)
- [IsSortedByKey](#issortedbykey)
- [Splice](#Splice)

Supported helpers for maps:

Expand Down Expand Up @@ -980,6 +981,25 @@ slice := lo.IsSortedByKey([]string{"a", "bb", "ccc"}, func(s string) int {

[[play](https://go.dev/play/p/wiG6XyBBu49)]

### Splice

Splice inserts multiple elements at index i. A negative index counts back from the end of the slice. The helper is protected against overflow errors.

```go
result := lo.Splice([]string{"a", "b"}, 1, "1", "2")
// []string{"a", "1", "2", "b"}

// negative
result = lo.Splice([]string{"a", "b"}, -1, "1", "2")
// []string{"a", "1", "2", "b"}

// overflow
result = lo.Splice([]string{"a", "b"}, 42, "1", "2")
// []string{"a", "b", "1", "2"}
```

[[play](https://go.dev/play/p/G5_GhkeSUBA)]

### Keys

Creates an array of the map keys.
Expand Down
24 changes: 24 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -625,3 +625,27 @@ func IsSortedByKey[T any, K constraints.Ordered](collection []T, iteratee func(i

return true
}

// Splice inserts multiple elements at index i. A negative index counts back
// from the end of the slice. The helper is protected against overflow errors.
// Play: https://go.dev/play/p/G5_GhkeSUBA
func Splice[T any](collection []T, i int, elements ...T) []T {
sizeCollection := len(collection)
sizeElements := len(elements)
output := make([]T, 0, sizeCollection+sizeElements) // preallocate memory for the output slice

if sizeElements == 0 {
return append(output, collection...) // simple copy
} else if i > sizeCollection {
// positive overflow
return append(append(output, collection...), elements...)
} else if i < -sizeCollection {
// negative overflow
return append(append(output, elements...), collection...)
} else if i < 0 {
// backward
i = sizeCollection + i
}

return append(append(append(output, collection[:i]...), elements...), collection[i:]...)
}
44 changes: 44 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,3 +801,47 @@ func TestIsSortedByKey(t *testing.T) {
return ret
}))
}

func TestSplice(t *testing.T) {
t.Parallel()
is := assert.New(t)

sample := []string{"a", "b", "c", "d", "e", "f", "g"}

// normal case
results := Splice(sample, 1, "1", "2")
is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, sample)
is.Equal([]string{"a", "1", "2", "b", "c", "d", "e", "f", "g"}, results)

// check there is no side effect
results = Splice(sample, 1)
results[0] = "b"
is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, sample)

// positive overflow
results = Splice(sample, 42, "1", "2")
is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, sample)
is.Equal(results, []string{"a", "b", "c", "d", "e", "f", "g", "1", "2"})

// negative overflow
results = Splice(sample, -42, "1", "2")
is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, sample)
is.Equal(results, []string{"1", "2", "a", "b", "c", "d", "e", "f", "g"})

// backard
results = Splice(sample, -2, "1", "2")
is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, sample)
is.Equal(results, []string{"a", "b", "c", "d", "e", "1", "2", "f", "g"})

results = Splice(sample, -7, "1", "2")
is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, sample)
is.Equal(results, []string{"1", "2", "a", "b", "c", "d", "e", "f", "g"})

// other
is.Equal([]string{"1", "2"}, Splice([]string{}, 0, "1", "2"))
is.Equal([]string{"1", "2"}, Splice([]string{}, 1, "1", "2"))
is.Equal([]string{"1", "2"}, Splice([]string{}, -1, "1", "2"))
is.Equal([]string{"1", "2", "0"}, Splice([]string{"0"}, 0, "1", "2"))
is.Equal([]string{"0", "1", "2"}, Splice([]string{"0"}, 1, "1", "2"))
is.Equal([]string{"1", "2", "0"}, Splice([]string{"0"}, -1, "1", "2"))
}

0 comments on commit fe16ff7

Please sign in to comment.