1 Star 1 Fork 0

bon-ami / eztools

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
pair.go 4.57 KB
一键复制 编辑 原始数据 按行查看 历史
package eztools
import (
"sort"
"golang.org/x/exp/constraints"
)
type pair[K constraints.Ordered, V comparable] struct {
key K
val V
}
// Pairs contains key-value pairs.
// Key needs to be orderable so that Sort() works
// Value needs to be comparable so that FindVal() works
type Pairs[K constraints.Ordered, V comparable] struct {
next int
sorted bool
pair []pair[K, V]
}
// Rewind used after Add() to reset and before GetNMove() to the first item
func (ps *Pairs[K, V]) Rewind() {
ps.next = 0
}
// Add appends values to the collection,
// moving cursor to the end
func (ps *Pairs[K, V]) Add(key K, val V) {
if ps.pair == nil || len(ps.pair) < 1 {
ps.sorted = true
} else {
ps.sorted = false
}
ps.pair = append(ps.pair, pair[K, V]{key, val})
ps.next = ps.Len()
}
// AddNSort appends values to the collection and sorts it,
// moving cursor to the end
func (ps *Pairs[K, V]) AddNSort(key K, val V) {
ps.next = ps.Len() + 1
if ps.pair != nil && len(ps.pair) > 0 && ps.IsSorted() {
i := sort.Search(len(ps.pair), func(ind int) bool {
return ps.pair[ind].key >= key
})
ps.pair = append(ps.pair, pair[K, V]{})
copy(ps.pair[i+1:], ps.pair[i:])
ps.pair[i] = pair[K, V]{key: key, val: val}
return
}
ps.pair = append(ps.pair, pair[K, V]{key, val})
ps.Sort()
}
// Next gets the current item in the collection and moves to the next
// call Rewind() after Add() to reset to and get the first item
// Return value:
// ErrOutOfBound if collection is exhausted
func (ps *Pairs[K, V]) GetNMove() (rK K, rV V, err error) {
if ps.pair == nil || ps.next >= len(ps.pair) || len(ps.pair) < 1 {
return rK, rV, ErrOutOfBound
}
defer func() {
ps.next++
}()
return ps.pair[ps.next].key, ps.pair[ps.next].val, nil
}
// Len gets size of the collection
func (ps Pairs[K, V]) Len() int {
return len(ps.pair)
}
// Get get values of an ellement in the collection
// cursor moves to the next of it
// Return value:
// ErrOutOfBound if collection is empty or index is not valid
func (ps *Pairs[K, V]) Get(index int) (rK K, rV V, err error) {
if ps.pair == nil || index >= len(ps.pair) || index < 0 {
return rK, rV, ErrOutOfBound
}
ps.next = index + 1
return ps.pair[index].key, ps.pair[index].val, nil
}
// Set sets values of an ellement in the collection
// cursor moves to the next of it
// this makes the collection unsorted
// Return value:
// ErrOutOfBound if collection is empty or index is not valid
func (ps *Pairs[K, V]) Set(index int, key K, val V) error {
if ps.pair == nil || index >= len(ps.pair) || index < 0 {
return ErrOutOfBound
}
ps.pair[index].key, ps.pair[index].val = key, val
ps.next = index + 1
ps.sorted = false
return nil
}
// SetPrev sets values of previous ellement in the collection,
// after calling GetNMove(). cursor not moved
// this makes the collection unsorted
// Return value:
// ErrOutOfBound if collection is empty
func (ps *Pairs[K, V]) SetPrev(key K, val V) error {
if ps.next < 1 {
return ErrOutOfBound
}
ps.next++ // 'cause Set() moves cursor
return ps.Set(ps.next-2, key, val)
}
// FindId find the first value whose **key** matches input
// moving cursor to the next of it
// Return value:
// ErrOutOfBound if collection is empty
// ErrNoValidResults when none found
func (ps *Pairs[K, V]) FindKey(s K) (ret V, err error) {
if ps.pair == nil {
return ret, ErrOutOfBound
}
if ps.sorted {
sort.Search(len(ps.pair), func(ind int) bool {
return ps.pair[ind].key >= s
})
}
err = ErrNoValidResults
for i, v := range ps.pair {
if v.key == s {
ps.next = i + 1
return v.val, nil
}
}
ps.next = ps.Len()
return
}
// FindStr find the first key whose **value** matches input
// moving cursor to the next of it
// Return value:
// ErrOutOfBound if collection is empty
// ErrNoValidResults when none found
func (ps *Pairs[K, V]) FindVal(s V) (ret K, err error) {
if ps.pair == nil {
return ret, ErrOutOfBound
}
err = ErrNoValidResults
for i, v := range ps.pair {
if v.val == s {
ps.next = i + 1
return v.key, nil
}
}
ps.next = ps.Len()
return
}
// Sort sorts the collection by key and Rewind()
func (ps *Pairs[K, V]) Sort() {
defer func() {
ps.sorted = true
}()
if ps.sorted || ps.pair == nil || len(ps.pair) < 2 {
return
}
sort.Slice(ps.pair, func(i, j int) bool {
return ps.pair[i].key < ps.pair[j].key
})
ps.Rewind()
}
func (ps Pairs[K, V]) IsSorted() bool {
if ps.pair == nil || len(ps.pair) < 2 {
ps.sorted = true
}
return ps.sorted
}
Go
1
https://gitee.com/bon-ami/eztools.git
git@gitee.com:bon-ami/eztools.git
bon-ami
eztools
eztools
v6.2.0

搜索帮助