github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/stacks/arraystack/arraystack.go (about) 1 // Package arraystack implements a stack backed by array list. 2 // 3 // Structure is not thread safe. 4 // 5 // Reference: https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Array 6 package arraystack 7 8 import ( 9 "fmt" 10 "strings" 11 12 "github.com/songzhibin97/go-baseutils/structure/lists/arraylist" 13 "github.com/songzhibin97/go-baseutils/structure/stacks" 14 ) 15 16 // Assert Stack implementation 17 var _ stacks.Stack[any] = (*Stack[any])(nil) 18 19 // Stack holds elements in an array-list 20 type Stack[E any] struct { 21 list *arraylist.List[E] 22 } 23 24 // New instantiates a new empty stack 25 func New[E any]() *Stack[E] { 26 return &Stack[E]{list: arraylist.New[E]()} 27 } 28 29 // Push adds a value onto the top of the stack 30 func (stack *Stack[E]) Push(value E) { 31 stack.list.Add(value) 32 } 33 34 // Pop removes top element on stack and returns it, or nil if stack is empty. 35 // Second return parameter is true, unless the stack was empty and there was nothing to pop. 36 func (stack *Stack[E]) Pop() (value E, ok bool) { 37 value, ok = stack.list.Get(stack.list.Size() - 1) 38 stack.list.Remove(stack.list.Size() - 1) 39 return 40 } 41 42 // Peek returns top element on the stack without removing it, or nil if stack is empty. 43 // Second return parameter is true, unless the stack was empty and there was nothing to peek. 44 func (stack *Stack[E]) Peek() (value E, ok bool) { 45 return stack.list.Get(stack.list.Size() - 1) 46 } 47 48 // Empty returns true if stack does not contain any elements. 49 func (stack *Stack[E]) Empty() bool { 50 return stack.list.Empty() 51 } 52 53 // Size returns number of elements within the stack. 54 func (stack *Stack[E]) Size() int { 55 return stack.list.Size() 56 } 57 58 // Clear removes all elements from the stack. 59 func (stack *Stack[E]) Clear() { 60 stack.list.Clear() 61 } 62 63 // Values returns all elements in the stack (LIFO order). 64 func (stack *Stack[E]) Values() []E { 65 size := stack.list.Size() 66 elements := make([]E, size, size) 67 for i := 1; i <= size; i++ { 68 elements[size-i], _ = stack.list.Get(i - 1) // in reverse (LIFO) 69 } 70 return elements 71 } 72 73 // String returns a string representation of container 74 func (stack *Stack[E]) String() string { 75 b := strings.Builder{} 76 b.WriteString("ArrayStack\n") 77 for index, value := range stack.list.Values() { 78 b.WriteString(fmt.Sprintf("(index:%d value:%v) ", index, value)) 79 } 80 return b.String() 81 } 82 83 // Check that the index is within bounds of the list 84 func (stack *Stack[E]) withinRange(index int) bool { 85 return index >= 0 && index < stack.list.Size() 86 } 87 88 // UnmarshalJSON @implements json.Unmarshaler 89 func (stack *Stack[E]) UnmarshalJSON(bytes []byte) error { 90 return stack.list.UnmarshalJSON(bytes) 91 } 92 93 // MarshalJSON @implements json.Marshaler 94 func (stack *Stack[E]) MarshalJSON() ([]byte, error) { 95 return stack.list.MarshalJSON() 96 }