| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package winman
- // Stack represents a stack of unique items
- type Stack []interface{}
- // Push puts an element on the stack
- // if the item is already in the stack, this operation does nothing
- func (s *Stack) Push(newItem interface{}) {
- if newItem == nil {
- panic("cannot add nil item to stack")
- }
- for _, item := range *s {
- if item == newItem {
- return
- }
- }
- *s = append(*s, newItem)
- }
- // Pop pops the stack returning and removing the topmost element
- func (s *Stack) Pop() interface{} {
- lenItems := len(*s)
- if lenItems == 0 {
- return nil
- }
- var item interface{}
- item, *s = (*s)[lenItems-1], (*s)[:lenItems-1]
- return item
- }
- // Remove removes the given item from the stack
- // if the item does not exist, this function does nothing
- func (s *Stack) Remove(item interface{}) {
- i := s.IndexOf(item)
- if i != -1 {
- *s = append((*s)[:i], (*s)[i+1:]...)
- }
- }
- // Item returns the given item from the stack
- // returns nil if the index is out of bounds
- func (s Stack) Item(i int) interface{} {
- if i < 0 || i >= len(s) {
- return nil
- }
- return s[i]
- }
- // IndexOf searches the stack for the given item and returns its index
- func (s Stack) IndexOf(searchItem interface{}) int {
- for i, item := range s {
- if item == searchItem {
- return i
- }
- }
- return -1
- }
- // Move finds an item in the stack and places it at the given index,
- // shifting items up or down to make space
- func (s *Stack) Move(item interface{}, targetIndex int) {
- oldIndex := s.IndexOf(item)
- if oldIndex == -1 {
- return
- }
- lenS := len(*s)
- if targetIndex < 0 || targetIndex >= lenS {
- targetIndex = lenS - 1
- }
- newStack := make([]interface{}, lenS)
- for i, j := 0, 0; i < lenS; j++ {
- if j == oldIndex {
- j++
- }
- if i == targetIndex {
- j--
- } else {
- newStack[i] = (*s)[j]
- }
- i++
- }
- newStack[targetIndex] = item
- *s = newStack
- }
- // Find searches the stack top down for an item that meets the custom
- // criteria specified by the passed function
- func (s Stack) Find(f func(item interface{}) bool) interface{} {
- for i := len(s) - 1; i >= 0; i-- {
- item := s[i]
- if f(item) {
- return item
- }
- }
- return nil
- }
|