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  }