123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- package sortedmap
- import (
- "container/list"
- "errors"
- "fmt"
- "strings"
- "github.com/zeromicro/go-zero/tools/goctl/util/stringx"
- )
- var (
- ErrInvalidKVExpression = errors.New(`invalid key-value expression`)
- ErrInvalidKVS = errors.New("the length of kv must be a even number")
- )
- type KV []interface{}
- type SortedMap struct {
- kv *list.List
- keys map[interface{}]*list.Element
- }
- func New() *SortedMap {
- return &SortedMap{
- kv: list.New(),
- keys: make(map[interface{}]*list.Element),
- }
- }
- func (m *SortedMap) SetExpression(expression string) (key, value interface{}, err error) {
- idx := strings.Index(expression, "=")
- if idx == -1 {
- return "", "", ErrInvalidKVExpression
- }
- key = expression[:idx]
- if len(expression) == idx {
- value = ""
- } else {
- value = expression[idx+1:]
- }
- if keys, ok := key.(string); ok && stringx.ContainsWhiteSpace(keys) {
- return "", "", ErrInvalidKVExpression
- }
- if values, ok := value.(string); ok && stringx.ContainsWhiteSpace(values) {
- return "", "", ErrInvalidKVExpression
- }
- if len(key.(string)) == 0 {
- return "", "", ErrInvalidKVExpression
- }
- m.SetKV(key, value)
- return
- }
- func (m *SortedMap) SetKV(key, value interface{}) {
- e, ok := m.keys[key]
- if !ok {
- e = m.kv.PushBack(KV{
- key, value,
- })
- } else {
- e.Value.(KV)[1] = value
- }
- m.keys[key] = e
- }
- func (m *SortedMap) Set(kv KV) error {
- if len(kv) == 0 {
- return nil
- }
- if len(kv)%2 != 0 {
- return ErrInvalidKVS
- }
- for idx := 0; idx < len(kv); idx += 2 {
- m.SetKV(kv[idx], kv[idx+1])
- }
- return nil
- }
- func (m *SortedMap) Get(key interface{}) (interface{}, bool) {
- e, ok := m.keys[key]
- if !ok {
- return nil, false
- }
- return e.Value.(KV)[1], true
- }
- func (m *SortedMap) GetOr(key, dft interface{}) interface{} {
- e, ok := m.keys[key]
- if !ok {
- return dft
- }
- return e.Value.(KV)[1]
- }
- func (m *SortedMap) GetString(key interface{}) (string, bool) {
- value, ok := m.Get(key)
- if !ok {
- return "", false
- }
- vs, ok := value.(string)
- return vs, ok
- }
- func (m *SortedMap) GetStringOr(key interface{}, dft string) string {
- value, ok := m.GetString(key)
- if !ok {
- return dft
- }
- return value
- }
- func (m *SortedMap) HasKey(key interface{}) bool {
- _, ok := m.keys[key]
- return ok
- }
- func (m *SortedMap) HasValue(value interface{}) bool {
- var contains bool
- m.RangeIf(func(key, v interface{}) bool {
- if value == v {
- contains = true
- return false
- }
- return true
- })
- return contains
- }
- func (m *SortedMap) Keys() []interface{} {
- keys := make([]interface{}, 0)
- next := m.kv.Front()
- for next != nil {
- keys = append(keys, next.Value.(KV)[0])
- next = next.Next()
- }
- return keys
- }
- func (m *SortedMap) Values() []interface{} {
- keys := m.Keys()
- values := make([]interface{}, len(keys))
- for idx, key := range keys {
- values[idx] = m.keys[key].Value.(KV)[1]
- }
- return values
- }
- func (m *SortedMap) Range(iterator func(key, value interface{})) {
- next := m.kv.Front()
- for next != nil {
- value := next.Value.(KV)
- iterator(value[0], value[1])
- next = next.Next()
- }
- }
- func (m *SortedMap) RangeIf(iterator func(key, value interface{}) bool) {
- next := m.kv.Front()
- for next != nil {
- value := next.Value.(KV)
- loop := iterator(value[0], value[1])
- if !loop {
- return
- }
- next = next.Next()
- }
- }
- func (m *SortedMap) Remove(key interface{}) (value interface{}, ok bool) {
- v, ok := m.keys[key]
- if !ok {
- return nil, false
- }
- value = v.Value.(KV)[1]
- ok = true
- m.kv.Remove(v)
- delete(m.keys, key)
- return
- }
- func (m *SortedMap) Insert(sm *SortedMap) {
- sm.Range(func(key, value interface{}) {
- m.SetKV(key, value)
- })
- }
- func (m *SortedMap) Copy() *SortedMap {
- sm := New()
- m.Range(func(key, value interface{}) {
- sm.SetKV(key, value)
- })
- return sm
- }
- func (m *SortedMap) Format() []string {
- format := make([]string, 0)
- m.Range(func(key, value interface{}) {
- format = append(format, fmt.Sprintf("%s=%s", key, value))
- })
- return format
- }
- func (m *SortedMap) Reset() {
- m.kv.Init()
- for key := range m.keys {
- delete(m.keys, key)
- }
- }
|