jrutil

package module
v0.0.0-...-92d51e1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2024 License: BSD-3-Clause Imports: 8 Imported by: 0

README

jrutil

Go Utility Library

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CountElements

func CountElements[T comparable](xs []T) map[T]int

CountElements counts the number of times that element occurs in the slice.

func Filter

func Filter[T any](xs []T, f func(x T) bool) []T

Filter uses the function f to filter the input slice xs. The return slice will hold only the values of xs for which f returned true.

func ForEachLine

func ForEachLine(
	r io.Reader,
	stripEOL bool,
	strict bool,
	fn func(string) (bool, error),
) error

ForEachLine invokes the function fn for each line of text in the io.Reader r.

If strict is true, this method uses [jrutil.ReadLine()] to get the next line which is slower but works with DOS, Mac, and UNIX EOL sequences. If strict is false (recommended), this method uses [bufio.ReadString()] which is over twice as fast and works with DOS and UNIX EOLs but not Mac EOLs.

If stripEOL is true, the EOLs will be stripped from the line before fn is called.

To receive the next line of text, fn must return (true, nil). If fn returns an error, it is forward to the caller as the error returned by ForEachLine(). If fn is translating input text and writing it back out, for best performance, fn should write to a bufio.Writer wrapper.

func IfElse

func IfElse[T any](b bool, consequent T, alternative T) T

IfElse is similar to C's ternary operator.

func MakePtr

func MakePtr[T any](x T) *T

MakePtr is useful for making pointers from intrinsic types like int for which the address-of operator does not work.

func MakeRandomBytes

func MakeRandomBytes(n uint64) ([]byte, error)

MakeRandomBytes returns a slice of bytes initialzed from crypto.rand.Read().

func Map

func Map[T1 any, T2 any](xs []T1, f func(T1) T2) []T2

Map use the function f to map each element of the input slice xs to the corresponding element in the output slice.

func MergeSlices

func MergeSlices[T cmp.Ordered](
	xs []T,
	ys []T,
	isLessThan func(x, y T) bool) []T

Merge merges the two sorted slices (xs and ys) and returns a new sorted slice that contains all of the elements from the two sorted input slices. This function performs a shallow copy when copying values from xs and ys to the result. Thus, if complex values are being sorted, xs and ys should hold pointers (for which shallow copying is correct).

func MergeSortSlices

func MergeSortSlices[T cmp.Ordered](
	xs []T,
	isLessThan func(x1, x2 T) bool) []T

MergeSort returns a new, sorted slice based on the comparison function f.

func NewRand

func NewRand() (*rand.Rand, error)

NewRand returns a new math.rand.Rand (v2) instance that uses source that is seeded with random bytes from crypto.rand.Read().

func Prompt

func Prompt(
	fin *bufio.Reader,
	fout *bufio.Writer,
	prompt string,
) (string, error)

Prompt prompts on fout for input and then reads a line of text from fin. The line of text is returned with the trailing EOL sequence removed.

In the common case of wanting to read and write from and to os.Stdin and os.Stdout, they should be wrapped to be buffered as follows which should only happen once probably early in your main() function:

fin := bufio.NewReader(os.Stdin)
fout := bufio.NewWriter(os.Stdout)

The reason for having to use buffered I/O for stdin and stdout is to avoid conflicts with other parts of the code that might need to use stdin and stdout. You cannot mix buffered I/O and non-buffered I/O without losing some bytes along the way. You cannot even create multiple buffered I/O wrappers around stdin or stdout without losing bytes along the way.

Also see PromptUnbuffered().

func PromptUnbuffered

func PromptUnbuffered(prompt string) (string, error)

Prompt prompts on os.Stdout for input and then reads a line of text from os.Stdin. The line of text is returned with the trailing EOL sequence removed.

Also see Prompt().

func ReadLine

func ReadLine(r *bufio.Reader) (string, error)

ReadLine returns the next line of text with EOL sequence still attached. Call [jrutil.StripEOL()] to remove the EOL sequence. Valid end-of-line sequences are "\r", "\n", or "\r\n". This method assumes the input stream is UTF-8 encoded. Performance should be improved if r is passed in as a bufio.Reader. Also see [ForEachLine()].

func Reduce

func Reduce[T1 any, T2 any](xs []T1, init T2, f func(T2, T1) T2) T2

Reduce uses the function f to reduce the input slice xs to a single output value. The accumulator is initialized with init. f will be called once for each element in xs with the accumulator as the first argument and the element of xs as the second argument. After calling f for all element of xs, the accumulator is returned.

func SliceToSet

func SliceToSet[T comparable](xs []T) map[T]int

SliceToSet returns the set of elements in the slice where the keys in the map that return for the elements in the set.

func StripEOL

func StripEOL(line string) string

StripEOL returns the line of text with its EOL sequence removed. This function strips Unix ('\n'), DOS ('\r\n'), and Mac ('\r') EOL sequences.

func SubtractSet

func SubtractSet[T comparable](xs, ys map[T]int) map[T]int

SubtractSet returns the set of elements in xs that are not in ys. This is the same as the "relative complement" of ys with respect to xs. The sets can be generated using SliceToSet.

func SubtractSlice

func SubtractSlice[T comparable](xs, ys []T) []T

SubtractSlice returns the slice of elements in xs that are not in ys. This is the same as the "relative complement" of ys with respect to xs.

Types

type Pair

type Pair[T1 any, T2 any] struct {
	First  T1
	Second T2
}

Pair holds a pair of values.

func MakePair

func MakePair[T1 any, T2 any](first T1, second T2) Pair[T1, T2]

MakePair returns a new Pair initialized with the first and second values.

func MapToPairs

func MapToPairs[T1 comparable, T2 any](m map[T1]T2) []Pair[T1, T2]

MapToPairs converts the key/value pairs in the unordered input map m to an unordered slice of key/value pairs. For example, if you want to sort the key/value pairs in a map by value, you can do the following:

// Create the map.
counts := map[string]uint64{
	"foo": 10,
	"bar": 3,
	"baz": 7,
}

// Convert the map into a list of key/value pairs.
kvPairs := jrutil.MapToPairs(counts)

// Sort the key/value pairs.
sort.Slice(kvPairs, func (i, j int) bool {
	return kvPairs[i].Second < kvPairs[j].Second
})

// Print the results.
for _, kvPair := range kvPairs {
	fmt.Printf("%v: %v\n", kvPair.First, kvPair.Second)
}

type SList

type SList[T any] struct {
	// contains filtered or unexported fields
}

SList is a value and a recursive pointer to another list.

func NewSList

func NewSList[T any]() *SList[T]

NewSList returns a new SList.

func NewSListFromSlice

func NewSListFromSlice[T any](xs []T) *SList[T]

NewSListFromSlice returns a new SList from the slice xs by performing a shallow copy on each element in xs.

func (*SList[T]) Contains

func (l *SList[T]) Contains(f func(x T) bool) bool

Contains returns true if the list contains an element that satisfies the predicate. Note that we cannot just pass in an element of type T to compare directly because T is constrained by "any" not "comparable". This is done so SList works with more types.

func (*SList[T]) Drop

func (l *SList[T]) Drop(n uint64) *SList[T]

Drop removes the first n elements from the front of the list. This method is relatively efficient because it does not have to allocate or deallocate any memory.

func (*SList[T]) DropUntil

func (l *SList[T]) DropUntil(f func(x T) bool) *SList[T]

DropUntil removes the elements from the head of the list until the predicate is true.

func (*SList[T]) DropWhile

func (l *SList[T]) DropWhile(f func(x T) bool) *SList[T]

DropWhile removes elements from the head of the list while the predicate is true.

func (*SList[T]) Empty

func (l *SList[T]) Empty() bool

Empty returns true if the list is empty; otherwise, it returns false.

func (*SList[T]) Equal

func (xs *SList[T]) Equal(
	ys *SList[T],
	isEqual func(x, y T) bool) bool

Equal returns true if the two lists have the same length and if every element in this xs list is equal to the corresponding element in the ys list as determined by the isEqual function.

func (*SList[T]) Head

func (l *SList[T]) Head() (T, bool)

Head returns the value at the front of the list.

func (*SList[T]) Length

func (l *SList[T]) Length() uint64

Length returns the length of the list. This method is O(1).

func (*SList[T]) Merge

func (xs *SList[T]) Merge(
	ys *SList[T],
	isLessThan func(x, y T) bool) *SList[T]

Merge the sorted lists xs and ys into a new sorted list and return the result.

func (*SList[T]) MergeSort

func (l *SList[T]) MergeSort(isLessThan func(l1, l2 T) bool) *SList[T]

func (*SList[T]) Nth

func (l *SList[T]) Nth(n uint64) (T, bool)

Nth returns the nth element (zero-based).

func (*SList[T]) PushFront

func (l *SList[T]) PushFront(value T) *SList[T]

PushFront appends the value to the front of the list. This method is O(1) is generally used to build the list back-to-front.

func (*SList[T]) Reverse

func (l *SList[T]) Reverse() *SList[T]

Reverse returns a new list that is the reverse of this list. This method is often necessary, but it is O(N) and should be used sparingly.

func (*SList[T]) String

func (l *SList[T]) String() string

String returns the string representation of the list.

func (*SList[T]) Tail

func (l *SList[T]) Tail() *SList[T]

Tail returns the rest of the list which is the same as Drop(1).

func (*SList[T]) Take

func (l *SList[T]) Take(n uint64) *SList[T]

Take returns the first n elements. This method is relatively inefficient because it has to build the new list that is returned. (Profiling shows this is implementation is faster (even for small lists) than a recursive implementation even though this implement requires a call to Reverse().)

func (*SList[T]) TakeUntil

func (l *SList[T]) TakeUntil(f func(x T) bool) *SList[T]

TakeUntil returns elements from the head of the list until the predicate is true. This method is O(N) and should be used sparingly if taking many elements.

func (*SList[T]) TakeWhile

func (l *SList[T]) TakeWhile(f func(x T) bool) *SList[T]

TakeWhile returns the elements from the head of the list while the predicate is true. This method is O(N) and should be used sparingly if taking many elements.

func (*SList[T]) ToSlice

func (l *SList[T]) ToSlice() []T

ToSlice returns a new slice having the same elements as this list. The slice is created using shallow copies of the elements of this list.

type Stack

type Stack[T comparable] struct {
	// contains filtered or unexported fields
}

Stack holds a stack of values implemented as a slice.

func NewStack

func NewStack[T comparable]() *Stack[T]

NewStack returns a new stack.

func (*Stack[T]) Contains

func (s *Stack[T]) Contains(item T) bool

Contains returns true if the stack contains the item; otherwise, it returns false.

func (*Stack[T]) Pop

func (s *Stack[T]) Pop() (T, bool)

Pop return the item at the top of the stack. If the stack is empty, false is returned.

func (*Stack[T]) Push

func (s *Stack[T]) Push(item T)

Push pushes the item onto the stack.

type Vector

type Vector[T any] []any

Vector is a type alias for []any.

func (Vector[T]) Insert

func (v Vector[T]) Insert(index uint64, value T) Vector[T]

Insert inserts the value at the index. If the index is greater than the length of the vector, the item is inserted at the end of the vector. This method is O(N) and should be used sparingly.

func (Vector[T]) PushBack

func (v Vector[T]) PushBack(value T) Vector[T]

PushBack appends the value to the end of the vector.

func (Vector[T]) PushFront

func (v Vector[T]) PushFront(value T) Vector[T]

PushFront appends the value to the front of the vector. This method is O(N) and should be used sparingly.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL