utils/slist.go

268 lines
5.4 KiB
Go

// simple-list project slist.go
package slist
import (
"fmt"
"portale-stac.it/packages/collections"
)
type SNode struct {
data interface{}
next *SNode
}
func (self *SNode) Data() interface{} {
return self.data
}
type SList struct {
count uint32
first *SNode
last *SNode
}
func NewSimpleList() (list *SList) {
list = &SList{0, nil, nil}
return
}
func (self *SList) Len() uint32 {
return self.count
}
func (self *SList) Empty() bool {
return self.count == 0
}
func (self *SList) PushFront(data interface{}) *SNode {
self.first = &SNode{data, self.first}
if self.last == nil {
self.last = self.first
}
self.count++
return self.first
}
func (self *SList) PushBack(data interface{}) (node *SNode) {
node = &SNode{data, nil}
if self.last != nil {
self.last.next = node
}
self.last = node
if self.first == nil {
self.first = node
}
self.count++
return
}
func (self *SList) FirstNode() (node *SNode, err error) {
if self.first != nil {
node = self.first
} else {
err = errorListEmpty()
}
return
}
func (self *SList) First() (data interface{}, err error) {
node, err := self.FirstNode()
if err == nil {
data = node.data
} else {
err = errorListEmpty()
}
return
}
func (self *SList) LastNode() (node *SNode, err error) {
if self.last != nil {
node = self.last
} else {
err = errorListEmpty()
}
return
}
func (self *SList) Last() (data interface{}, err error) {
node, err := self.LastNode()
if err == nil {
data = node.data
}
return
}
func (self *SList) NodeAt(index uint32) (node *SNode, err error) {
if self.count == 0 {
err = errorListEmpty()
} else if index > self.count {
err = errorOutOfRange()
} else if index == self.count-1 {
node = self.last
} else {
current := self.first
for pos := uint32(0); pos < index; pos++ {
current = current.next
}
node = current
}
return
}
func (self *SList) At(index uint32) (data interface{}, err error) {
node, err := self.NodeAt(index)
if err == nil {
data = node.data
}
return
}
func (self *SList) Insert(index uint32, data interface{}) *SNode {
var prev *SNode
prev = nil
current := self.first
for pos := uint32(0); current != nil && pos < index; pos++ {
prev = current
current = current.next
}
node := &SNode{data, current}
if prev != nil {
prev.next = node
}
if self.first == current {
self.first = node
}
if node.next == nil {
self.last = node
}
self.count++
return node
}
func (self *SList) PushBackStringArray(items []string) {
for _, v := range items {
self.PushBack(v)
}
}
type TraverseOperator func(index uint32, elem interface{}, userData interface{}) (err error)
func (self *SList) Traverse(op TraverseOperator, user_data interface{}) (err error) {
index := uint32(0)
for current := self.first; current != nil; current = current.next {
err = op(index, current.data, user_data)
if err != nil {
break
}
index++
}
return
}
func (self *SList) Traverse2(observer collections.Observer, abortOnError bool) (err error) {
index := uint32(0)
for current := self.first; current != nil; current = current.next {
err = observer.Observe(current, index)
if err != nil && abortOnError {
break
}
index++
}
return
}
type EqualFunc func(current, target any) bool
func (self *SList) FindFirst(eqFunc EqualFunc, targetData any) (targetNode *SNode) {
for current := self.first; current != nil && targetNode == nil; current = current.next {
if eqFunc(current.data, targetData) {
targetNode = current
}
}
return
}
func (self *SList) FindNext(eqFunc EqualFunc, startNode *SNode) (targetNode *SNode) {
if startNode != nil {
for current := startNode.next; current != nil && targetNode == nil; current = current.next {
if eqFunc(current.data, startNode.Data()) {
targetNode = current
}
}
}
return
}
type DataFeeder func(user_data interface{}) interface{}
type NodeObserver func(node *SNode, index uint32, userData interface{})
func (self *SList) FeedTail(feeder DataFeeder, feederUserData interface{}, observer NodeObserver, observerUserData interface{}) (count uint32) {
count = 0
for item := feeder(feederUserData); item != nil; item = feeder(feederUserData) {
// fmt.Println("Item", count, item)
node := self.PushBack(item)
if observer != nil {
observer(node, count, observerUserData)
}
count++
}
return
}
func (self *SList) FeedTail2(feeder collections.Feeder, observer collections.Observer, abortOnError bool) (count uint32, err error) {
count = 0
// item := feeder.Next()
for item, err1 := feeder.Next(); item != nil; item, err1 = feeder.Next() {
if err1 != nil {
if err == nil {
err = err1
}
if abortOnError {
break
}
}
// fmt.Println("Item", count, item)
node := self.PushBack(item)
if observer != nil {
observer.Observe(node, count)
}
count++
}
return
}
// func (self *SList) FeedTail2(feeder collections.Feeder, observer NodeObserver, observerUserData interface{}, abortOnError bool) (count uint32, err error) {
// count = 0
// // item := feeder.Next()
// for item, err1 := feeder.Next(); item != nil; item, err1 = feeder.Next() {
// if err1 != nil {
// if err == nil {
// err = err1
// }
// if abortOnError {
// break
// }
// }
// // fmt.Println("Item", count, item)
// node := self.PushBack(item)
// if observer != nil {
// observer(node, count, observerUserData)
// }
// count++
// }
// return
// }
func errorListEmpty() error {
return fmt.Errorf("List is empty")
}
func errorOutOfRange() error {
return fmt.Errorf("Out of range")
}