github.com/avicd/go-utilx@v0.1.0/datax/linkedList.go (about) 1 package datax 2 3 type LinkedList[T any] struct { 4 head *LinkedNode[T] 5 end *LinkedNode[T] 6 size int 7 } 8 9 func (it *LinkedList[T]) First() (T, bool) { 10 var ret T 11 if it.head != nil { 12 ret = it.head.Item 13 } else { 14 return ret, false 15 } 16 return ret, true 17 } 18 19 func (it *LinkedList[T]) Last() (T, bool) { 20 var ret T 21 if it.end != nil { 22 ret = it.end.Item 23 } else { 24 return ret, false 25 } 26 return ret, true 27 } 28 29 func (it *LinkedList[T]) Push(item T) int { 30 it.end = it.end.Append(item) 31 if it.head == nil { 32 it.head = it.end 33 } 34 it.size++ 35 return it.size 36 } 37 38 func (it *LinkedList[T]) Pop() (T, bool) { 39 var ret T 40 if it.end == nil { 41 return ret, false 42 } 43 ret = it.end.Item 44 if it.head == it.end { 45 it.head = nil 46 it.end = nil 47 } else if it.end.Pre != nil { 48 it.end = it.end.Pre 49 it.end.Next.Remove() 50 } else { 51 it.end = nil 52 } 53 it.size-- 54 return ret, true 55 } 56 57 func (it *LinkedList[T]) Unshift(item T) int { 58 node := &LinkedNode[T]{Item: item} 59 if it.head == nil { 60 it.head = node 61 it.end = node 62 } else { 63 it.head.Insert(node) 64 it.head = node 65 } 66 it.size++ 67 return it.size 68 } 69 70 func (it *LinkedList[T]) Shift() (T, bool) { 71 var ret T 72 if it.head == nil { 73 return ret, false 74 } 75 ret = it.end.Item 76 if it.head == it.end { 77 it.head = nil 78 it.end = nil 79 } else if it.head.Next != nil { 80 it.head = it.head.Next 81 it.head.Pre.Remove() 82 } else { 83 it.head = nil 84 } 85 it.size-- 86 return ret, true 87 } 88 89 func (it *LinkedList[T]) Len() int { 90 return it.size 91 } 92 93 func (it *LinkedList[T]) nodeOf(index int) *LinkedNode[T] { 94 var node *LinkedNode[T] 95 if index < (it.size >> 1) { 96 node = it.head 97 for i := 0; i < index; i++ { 98 node = node.Next 99 } 100 } else { 101 node = it.end 102 for i := it.size - 1; i > index; i-- { 103 node = node.Pre 104 } 105 } 106 return node 107 } 108 109 func (it *LinkedList[T]) Get(index int) (T, bool) { 110 var ret T 111 if it.size < 1 || index < 0 || index >= it.size { 112 return ret, false 113 } else { 114 ret = it.nodeOf(index).Item 115 } 116 return ret, true 117 } 118 119 func (it *LinkedList[T]) Remove(index int) int { 120 if it.size < 1 || index < 0 || index >= it.size { 121 return it.size 122 } else { 123 node := it.nodeOf(index) 124 if it.head == node { 125 it.head = it.head.Next 126 } 127 if it.end == node { 128 it.end = it.end.Pre 129 } 130 node.Remove() 131 it.size-- 132 } 133 return it.size 134 } 135 136 func (it *LinkedList[T]) Clear() { 137 it.head = nil 138 it.end = nil 139 it.size = 0 140 } 141 142 func (it *LinkedList[T]) ForEach(fn func(i int, item T)) { 143 index := 0 144 for p := it.head; p != nil; p = p.Next { 145 fn(index, p.Item) 146 index++ 147 } 148 }