Algorithms Not in GoLanguage Standard library
As the name implies, there are (or were at the time of writing) commonly required operations/algorithms that are not provided in the language standard library. This library is a slowly growing collection of such things. (As of time of writing it does not contain any generic, but the plan is to sort that in the coming weeks.)
As an example, the standard library's strings package provides the following functions to split a string into []string:
funcSplit(s, sepstring) []stringfuncSplitN(s, sepstring, nint) []stringfuncSplitAfter(s, sepstring) []stringfuncSplitAfterN(s, sepstring, nint) []stringANGoLS provides a bunch of additional split functions that provide more expressiveness and/or functionality not possible with the standard library functions, including:
funcSplitAfterByte(sstring, sepbyte) []stringfuncSplitAfterByteN(sstring, sepbyte, ixint) []stringfuncSplitAfterRune(sstring, seprune) []stringfuncSplitAfterRuneN(sstring, seprune, ixint) []stringfuncSplitAfterAny(s, charsstring) []stringfuncSplitAfterAnyN(s, charsstring, ixint) []stringfuncSplitAfterAnyBytes(sstring, seps []byte) []stringfuncSplitAfterAnyBytesN(sstring, seps []byte, ixint) []stringfuncSplitAfterAnyRunes(sstring, seps []rune) []stringfuncSplitAfterAnyRunesN(sstring, seps []rune, ixint) []stringgo get "github.com/synesissoftware/ANGoLS"import (
angols_slices "github.com/synesissoftware/ANGoLS/slices"
angols_strings "github.com/synesissoftware/ANGoLS/strings"
)Modelled after Ruby's Enumerable#collect(), these functions provide for transforming a slice of a given type with given values into a same-sized slice of a given type with transformed values.
// in "github.com/synesissoftware/ANGoLS/slices"// This function maps an input slice of T[] to an output slice of []T.funcCollectSlice[Tany](input_slice []T, collectorfunc(indexint, input_item*T) (T, error)) ([]T, error)
// This function maps an input slice of []int to an output slice of []int.funcCollectSliceOfInt(input_slice []int, collectorfunc(input_itemint) int) (result_slice []int)
// This function maps an input slice of []N to an output slice of []N, where// N is any integer type.funcCollectSliceOfInteger[Nint8|int16|int32|int64|int|uint8|uint16|uint32|uint64|uint|uintptr](input_slice []N, collectorfunc(input_itemN) N) (result_slice []N)
// This function maps an input slice of []float64 to an output slice of// []float64.funcCollectSliceOfFloat64(input_slice []float64, collectorfunc(input_itemfloat64) float64) (result_slice []float64)
// This function maps an input slice of []string to an output slice of// []string.funcCollectSliceOfString(input_slice []string, collectorfunc(input_itemstring) string) (result_slice []string)
// This function maps an input slice of []T to an output slice of []string.funcCollectSliceIntoStringSlice[Tany](input_slice []T, collectorfunc(input_item*T) (string, error)) ([]string, error)Functions for evaluating equality between slices, in terms of both length and contents (values and ordering).
// in "github.com/synesissoftware/ANGoLS/slices"// Indicates whether two []int slices have the same size, contents, and// order.funcEqualSliceOfInt(lhs, rhs []int) bool// Indicates whether two []uint slices have the same size, contents, and// order.funcEqualSliceOfUint(lhs, rhs []uint) boolfuncEqualSliceOfInteger[Nint8|int16|int32|int64|int|uint8|uint16|uint32|uint64|uint|uintptr](lhs, rhs []int) bool// Indicates whether two []float64 slices have the same size, contents, and// order.funcEqualSliceOfFloat64(lhs, rhs []float64) bool// Indicates whether two []string slices have the same size, contents, and// order.funcEqualSliceOfString(lhs, rhs []string) boolfuncEqualSlice(lhs, rhsany) boolFunctions for generating slices of a given size and type from a generator function.
// in "github.com/synesissoftware/ANGoLS/slices"// Creates a slice of a given size and populates its values with the given// generator (which may be nil).funcGenerateSliceOfInt(sizeint, generatorfunc(indexint) (resultint, errerror)) (result []int, errerror)
// Creates a slice of a given size and populates its values with the given// generator (which may be nil).funcGenerateSliceOfUint(sizeint, generatorfunc(indexint) (resultuint, errerror)) (result []uint, errerror)
// Creates a slice of a given size and populates its values with the given// generator (which may be nil).funcGenerateSliceOfString(sizeint, generatorfunc(indexint) (resultstring, errerror)) (result []string, errerror)Modelled after Ruby's Enumerable#select(), these functions provide for selecting elements of a given slice of a given type into a new slice of the given type.
// in "github.com/synesissoftware/ANGoLS/slices"funcSelectSliceOfInt(input_slice []int, selectorfunc(indexint, input_itemint) (bool, error)) ([]int, error)
funcSelectSliceOfUint(input_slice []uint, selectorfunc(indexint, input_itemuint) (bool, error)) ([]uint, error)
funcSelectSliceOfInteger[Nint8|int16|int32|int64|int|uint8|uint16|uint32|uint64|uint|uintptr](input_slice []N, selectorfunc(indexint, input_itemN) (bool, error)) ([]N, error)
funcSelectSliceOfString(input_slice []string, selectorfunc(indexint, input_itemstring) (bool, error)) ([]string, error)// in "github.com/synesissoftware/ANGoLS/strings"// Returns a copy of s with all uppercase ASCII letters converted to their// lowercase equivalents. Non-ASCII bytes and non-uppercase letters are left// unchanged.//// The prime use-case for this function is when dealing with strings that// are known to contain only ASCII and a faster conversion than is provided// by the standard `ToLower()` is desired.funcASCIIToLower(sstring) string// Returns a copy of s with all lowercase ASCII letters converted to their// uppercase equivalents. Non-ASCII bytes and non-lowercase letters are left// unchanged.//// The prime use-case for this function is when dealing with strings that// are known to contain only ASCII and a faster conversion than is provided// by the standard `ToUpper()` is desired.funcASCIIToUpper(sstring) string// Finds the index of the given substring in the given string, starting from// the position after the given index. -1 is returned if the find is not// successful.//// To search from the start of the string, specify the value -1 for the// index. Any index value less than -1 will be treated as if -1 specified.// Any index value greater than the size of the string will result in a// return value of -1.//// The returned value reflects the position of the found substring relative// to the start of the string, not from the index.funcIndexAfter(sstring, sfstring, ixint) int// Finds the index of the first instance of any character in chars, starting// from the position after the given index. -1 is returned if the find is// not successful.//// To search from the start of the string, specify the value -1 for the// index. Any index value less than -1 will be treated as if -1 specified.// Any index value greater than the size of the string will result in a// return value of -1.//// The returned value reflects the position of the found character relative// to the start of the string, not from the index.funcIndexAnyAfter(sstring, charsstring, ixint) int// Finds the index of the given byte in the given string, starting from the// position after the given index. -1 is returned if the find is not// successful.//// To search from the start of the string, specifying the value -1 for the// index. Any index value less than -1 will be treated as if -1 specified.// Any index value greater than the size of the string will result in a// return value of -1.//// The returned value reflects the position of the found byte relative to// the start of the string, not from the index.funcIndexByteAfter(sstring, cbyte, ixint) int// Finds the index of a character identified by the given function, starting// from the position after the given index. -1 is returned if the find is// not successful.//// To search from the start of the string, specifying the value -1 for the// index. Any index value less than -1 will be treated as if -1 specified.// Any index value greater than the size of the string will result in a// return value of -1.//// The returned value reflects the position of the identified character// relative to the start of the string, not from the index.funcIndexFuncAfter(sstring, ffunc(rune) bool, ixint) int// Finds the index of the first instance of any character not in chars,// starting from the position after the given index. -1 is returned if the// find is not successful.//// To search from the start of the string, specify the value -1 for the// index. Any index value less than -1 will be treated as if -1 specified.// Any index value greater than the size of the string will result in a// return value of -1.//// The returned value reflects the position of the found character relative// to the start of the string, not from the index.funcIndexNotAnyAfter(sstring, charsstring, ixint) int// in "github.com/synesissoftware/ANGoLS/strings"// Slices a string into all substings after each instance of the byte sep// and returns a slice of those substrings.//// If s does not contain sep, SplitAfterByte returns a slice of length 1// whose only element is s.//// It is equivalent to [SplitAfterByteN] with a count of -1.funcSplitAfterByte(sstring, sepbyte) []string// Slices s into substrings after each instance of the byte sep and returns// a slice of those substrings.//// ix determines the number of substrings to return:// - n > 0: at most n substrings; the last substring being the unsplit// remainder;// - n == 0: the result is nil (zero substrings);// - n < 0: all substrings.funcSplitAfterByteN(sstring, sepbyte, ixint) []string// Slices a string into all substings after each instance of the rune sep// and returns a slice of those substrings.//// If s does not contain sep, SplitAfterRune returns a slice of length 1// whose only element is s.//// It is equivalent to [SplitAfterRuneN] with a count of -1.funcSplitAfterRune(sstring, seprune) []string// Slices s into substrings after each instance of the rune sep and returns// a slice of those substrings.//// ix determines the number of substrings to return:// - n > 0: at most n substrings; the last substring being the unsplit// remainder;// - n == 0: the result is nil (zero substrings);// - n < 0: all substrings.funcSplitAfterRuneN(sstring, seprune, ixint) []string// Slices a string into all substings after each instance of any of the// runes in chars and returns a slice of those substrings.//// If s does not contain any of the runes in chars and chars is not empty,// SplitAfterAny returns a slice of length 1 whose only element is s.//// It is equivalent to [SplitAfterAnyN] with a count of -1.funcSplitAfterAny(s, charsstring) []string// Slices s into substrings after each instance of any of the runes in chars// and returns a slice of those substrings.//// ix determines the number of substrings to return:// - n > 0: at most n substrings; the last substring being the unsplit// remainder;// - n == 0: the result is nil (zero substrings);// - n < 0: all substrings.funcSplitAfterAnyN(s, charsstring, ixint) []string// Slices a string into all substings after each instance of any of the// bytes in seps and returns a slice of those substrings.//// If s does not contain any of the bytes in seps and seps is not empty,// SplitAfterAnyBytes returns a slice of length 1 whose only element is s.//// It is equivalent to [SplitAfterAnyBytesN] with a count of -1.funcSplitAfterAnyBytes(sstring, seps []byte) []string// Slices a string into all substings after each instance of any of the// bytes in seps and returns a slice of those substrings.//// ix determines the number of substrings to return:// - n > 0: at most n substrings; the last substring being the unsplit// remainder;// - n == 0: the result is nil (zero substrings);// - n < 0: all substrings.funcSplitAfterAnyBytesN(sstring, seps []byte, ixint) []string// Slices a string into all substings after each instance of any of the// runes in seps and returns a slice of those substrings.//// If s does not contain any of the runes in seps and seps is not empty,// SplitAfterAnyRunes returns a slice of length 1 whose only element is s.//// It is equivalent to [SplitAfterAnyN] with a count of -1.funcSplitAfterAnyRunes(sstring, seps []rune) []string// Slices a string into all substings after each instance of any of the// runes in seps and returns a slice of those substrings.//// ix determines the number of substrings to return:// - n > 0: at most n substrings; the last substring being the unsplit// remainder;// - n == 0: the result is nil (zero substrings);// - n < 0: all substrings.funcSplitAfterAnyRunesN(sstring, seps []rune, ixint) []string// in "github.com/synesissoftware/ANGoLS/strings"// Takes a single string and returns a chomped version of it, where chomping// removes a single trailing '\n' character, a single trailing '\r'// character, or a single trailing sequence of "\r\n".funcStringChomp(sstring) string// Takes a single string and returns a fully/repeatedly chomped version of,// where full/repeated chomping removes all trailing '\r' and/or '\n'// characters.funcStringChompAll(sstring) stringExamples are provided in the examples directory, along with a markdown description for each. A detailed list TOC of them is provided in EXAMPLES.md.
Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/ANGoLS.
Projects in which ANGoLS is used include:
- CLASP.Go (development/testing);
- libCLImate.Go;
- libpath.Go.
ANGoLS is released under the 3-clause BSD license. See LICENSE for details.