// simple-list project slist.go package kern import ( "fmt" ) type ListNode struct { data any next *ListNode } func (node *ListNode) Next() *ListNode { return node.next } func (self *ListNode) Data() any { return self.data } type LinkedList struct { count uint32 first *ListNode last *ListNode } func NewLinkedList() (list *LinkedList) { list = &LinkedList{0, nil, nil} return } func (ls *LinkedList) Len() uint32 { return ls.count } func (ls *LinkedList) Empty() bool { return ls.count == 0 } func (ls *LinkedList) PushFront(data any) *ListNode { ls.first = &ListNode{data, ls.first} if ls.last == nil { ls.last = ls.first } ls.count++ return ls.first } func (ls *LinkedList) SeqPushFront(data any) (result *LinkedList) { switch seq := data.(type) { case Iterator: result = ls.IterPushFront(seq) default: ls.PushFront(data) result = ls } return } func (ls *LinkedList) IterPushFront(it Iterator) *LinkedList { for item, err1 := it.Next(); err1 == nil; item, err1 = it.Next() { ls.PushFront(item) } return ls } func (ls *LinkedList) PushBack(data any) (node *ListNode) { node = &ListNode{data, nil} if ls.last != nil { ls.last.next = node } ls.last = node if ls.first == nil { ls.first = node } ls.count++ return } func (ls *LinkedList) SeqPushBack(data any) (result *LinkedList) { switch seq := data.(type) { case Iterator: result = ls.IterPushBack(seq) default: ls.PushBack(data) result = ls } return } func (ls *LinkedList) IterPushBack(it Iterator) *LinkedList { for item, err1 := it.Next(); err1 == nil; item, err1 = it.Next() { ls.PushBack(item) } return ls } func (ls *LinkedList) FirstNode() *ListNode { return ls.first } func (ls *LinkedList) First() (data any, err error) { if ls.first != nil { data = ls.first.data } else { err = errorListEmpty() } return } func (ls *LinkedList) LastNode() *ListNode { return ls.last } func (ls *LinkedList) Last() (data interface{}, err error) { if ls.last != nil { data = ls.last.data } else { err = errorListEmpty() } return } func (ls *LinkedList) NodeAt(index uint32) (node *ListNode, err error) { if ls.count == 0 { err = errorListEmpty() } else if index > ls.count { err = errorOutOfRange() } else if index == ls.count-1 { node = ls.last } else { current := ls.first for pos := uint32(0); pos < index; pos++ { current = current.next } node = current } return } func (ls *LinkedList) At(index uint32) (data interface{}, err error) { node, err := ls.NodeAt(index) if err == nil { data = node.data } return } func (ls *LinkedList) Insert(index uint32, data interface{}) *ListNode { var prev *ListNode prev = nil current := ls.first for pos := uint32(0); current != nil && pos < index; pos++ { prev = current current = current.next } node := &ListNode{data, current} if prev != nil { prev.next = node } if ls.first == current { ls.first = node } if node.next == nil { ls.last = node } ls.count++ return node } func (ls *LinkedList) PushBackStringArray(items []string) { for _, v := range items { ls.PushBack(v) } } // type TraverseOperator func(index uint32, elem interface{}, userData interface{}) (err error) // func (self *LinkedList) 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 *LinkedList) Traverse2(observer 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 (ls *LinkedList) FindFirst(eqFunc EqualFunc, targetData any) (targetNode *ListNode) { for current := ls.first; current != nil && targetNode == nil; current = current.next { if eqFunc(current.data, targetData) { targetNode = current } } return } func (ls *LinkedList) FindNext(eqFunc EqualFunc, startNode *ListNode) (targetNode *ListNode) { 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 *ListNode, index uint32, userData interface{}) // func (self *LinkedList) 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 *LinkedList) FeedTail2(feeder Feeder, observer 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 errorListEmpty() error { return fmt.Errorf("List is empty") } func errorOutOfRange() error { return fmt.Errorf("Out of range") }