v1.17.3
ADDED: * slicesx.First * slicesx.FirstIndex * slicesx.Remove * slicesx.RemoveAll * slicesx.RemoveReverse
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Package slicesx aims to extend functionality of the stdlib [slices] module.
|
Package slicesx aims to extend functionality of the stdlib [slices] module.
|
||||||
|
|
||||||
|
Most are convenience functions that aid in readability (sometimes at a VERY negligible performance hit),
|
||||||
|
but others can be quite useful (e.g. [Remove], [RemoveAll], [RemoveReverse]) that will save on significant boilerplate.
|
||||||
*/
|
*/
|
||||||
package slicesx
|
package slicesx
|
||||||
|
|||||||
+146
-1
@@ -1,10 +1,51 @@
|
|||||||
package slicesx
|
package slicesx
|
||||||
|
|
||||||
|
import (
|
||||||
|
`slices`
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
First returns the first item/element in slice s.
|
||||||
|
|
||||||
|
e will be the nil/zero value of the slice element type
|
||||||
|
if the slice length is 0 (including if s == nil).
|
||||||
|
*/
|
||||||
|
func First[S ~[]E, E any](s S) (e E) {
|
||||||
|
|
||||||
|
if len(s) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
e = s[0]
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
FirstIndex returns the index of the first element in slice s.
|
||||||
|
|
||||||
|
While at first glance this may seem useless, it may have some usecases as instead of causing panics:
|
||||||
|
|
||||||
|
* If s is empty, idx will be -1.
|
||||||
|
* If s is nil, idx will be -2.
|
||||||
|
* Otherwise idx will ALWAYS be 0.
|
||||||
|
*/_
|
||||||
|
func FirstIndex[S ~[]E, E any](s S) (idx int) {
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
idx = -2
|
||||||
|
} else if len(s) == 0 {
|
||||||
|
idx = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Last returns the last item/element in slice s.
|
Last returns the last item/element in slice s.
|
||||||
|
|
||||||
e will be the nil/zero value of the slice element type
|
e will be the nil/zero value of the slice element type
|
||||||
if the slice length is 0.
|
if the slice length is 0 (including if s == nil).
|
||||||
*/
|
*/
|
||||||
func Last[S ~[]E, E any](s S) (e E) {
|
func Last[S ~[]E, E any](s S) (e E) {
|
||||||
|
|
||||||
@@ -41,3 +82,107 @@ func LastIndex[S ~[]E, E any](s S) (idx int) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove removes any values of value elem from slice s up to max number of elems.
|
||||||
|
|
||||||
|
If maxRemove is negative (< 0), start from the end instead.
|
||||||
|
This simply wraps [RemoveReverse]:
|
||||||
|
|
||||||
|
removed = slicesx.RemoveReverse(s, elem, uint(-maxRemove))
|
||||||
|
|
||||||
|
If maxRemove is exactly 0, remove ALL instances of elem.
|
||||||
|
|
||||||
|
If s is nil, removed will be nil as well.
|
||||||
|
|
||||||
|
Note that s will remain untouched, and removed will be a new slice.
|
||||||
|
*/
|
||||||
|
func Remove[S ~[]E, E comparable](s S, elem E, maxRemove int) (removed S) {
|
||||||
|
|
||||||
|
var idx int
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(s) == 0 {
|
||||||
|
removed = []E{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
removed = make(S, 0, len(s))
|
||||||
|
defer func() {
|
||||||
|
if removed != nil {
|
||||||
|
removed = slices.Clip(removed)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if maxRemove < 0 {
|
||||||
|
removed = RemoveReverse(s, elem, uint(-maxRemove))
|
||||||
|
return
|
||||||
|
} else if maxRemove == 0 {
|
||||||
|
maxRemove = len(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx = range s {
|
||||||
|
if s[idx] == elem && maxRemove > 0 {
|
||||||
|
maxRemove--
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
removed = append(removed, s[idx])
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
RemoveAll is simply a convenience wrapper around [Remove], e.g.:
|
||||||
|
|
||||||
|
removed = slicesx.Remove(s, elem, 0)
|
||||||
|
*/
|
||||||
|
func RemoveAll[S ~[]E, E comparable](s S, elem E) (removed S) { return Remove(s, elem, 0) }
|
||||||
|
|
||||||
|
/*
|
||||||
|
RemoveReverse removes any values of value elem from slice s up to max number of elems in reverse order
|
||||||
|
(i.e. starting from the END of s).
|
||||||
|
|
||||||
|
If maxRemove is exactly 0, remove all instances of elem (via [RemoveAll]), i.e.:
|
||||||
|
|
||||||
|
removed = slicesx.RemoveAll(s, elem)
|
||||||
|
// or, more directly:
|
||||||
|
removed = slicesx.Remove(s, elem, 0)
|
||||||
|
|
||||||
|
If s is nil, removed will be nil as well.
|
||||||
|
|
||||||
|
Note that s will remain untouched, and removed will be a new slice.
|
||||||
|
*/
|
||||||
|
func RemoveReverse[S ~[]E, E comparable](s S, elem E, maxRemove uint) (removed S) {
|
||||||
|
|
||||||
|
var idx int
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(s) == 0 {
|
||||||
|
removed = []E{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if maxRemove == 0 {
|
||||||
|
removed = RemoveAll(s, elem)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
removed = make(S, 0, len(s))
|
||||||
|
|
||||||
|
for idx = len(s) - 1; idx >= 0; idx-- {
|
||||||
|
if s[idx] == elem && maxRemove > 0 {
|
||||||
|
maxRemove--
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
removed = append(removed, s[idx])
|
||||||
|
}
|
||||||
|
removed = slices.Clip(removed)
|
||||||
|
slices.Reverse(removed)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -636,7 +636,7 @@ pre.rouge .gs {
|
|||||||
<div class="details">
|
<div class="details">
|
||||||
<span id="author" class="author">Brent Saner</span><br>
|
<span id="author" class="author">Brent Saner</span><br>
|
||||||
<span id="email" class="email"><a href="mailto:bts@square-r00t.net">bts@square-r00t.net</a></span><br>
|
<span id="email" class="email"><a href="mailto:bts@square-r00t.net">bts@square-r00t.net</a></span><br>
|
||||||
<span id="revdate">Last rendered 2026-08-08 00:30:44 -0400</span>
|
<span id="revdate">Last rendered 2026-09-03 16:25:31 -0400</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="toc" class="toc2">
|
<div id="toc" class="toc2">
|
||||||
<div id="toctitle">Table of Contents</div>
|
<div id="toctitle">Table of Contents</div>
|
||||||
|
|||||||
+214
-216
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user