orderedmap

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2023 License: MIT Imports: 7 Imported by: 10

README

orderedmap Go Reference CI Status MIT License

An ordered map for Golang.

This library provides the following functionalities:

  • A map which is like a Go standard map, and provide same methods with Go sync.Map except CompareAndDelete and CompareAndSwap. (Concurrent use is not supported.)
  • Front and Back methods that iterates map entries in the order of key insertions.
  • Ldelete and LoadAndLdelete methods for logical deletions, because Store and Delete are slower than Go standard map.
  • LoadOrStoreFunc method which stores a result of a give function when an entry for the specified key is not present.
  • MarshalJSON and UnmarshalJSON methods for JSON serialization and deserialization. These methods are implementations of json.Marshaler and json.Unmarshaler interfaces.

Importing this package

import "github.com/sttk/orderedmap"

Usage

The usage of this package is described on the overview in the go package document.

See https://pkg.go.dev/github.com/sttk/orderedmap#pkg-overview.

Supporting Go versions

This framework supports Go 1.18 or later.

Actual test results for each Go version:
% gvm-fav
Now using version go1.18.10
go version go1.18.10 darwin/amd64
ok  	github.com/sttk/orderedmap	0.136s	coverage: 99.3% of statements

Now using version go1.19.10
go version go1.19.10 darwin/amd64
ok  	github.com/sttk/orderedmap	0.132s	coverage: 99.3% of statements

Now using version go1.20.5
go version go1.20.5 darwin/amd64
ok  	github.com/sttk/orderedmap	0.137s	coverage: 99.3% of statements

Back to go1.20.5
Now using version go1.20.5

License

Copyright (C) 2023 Takayuki Sato

This program is free software under MIT License.
See the file LICENSE in this distribution for more details.

Documentation

Overview

Package orderedmap provides Map type which is a map preserving the order of key insertions.

Usage

To create an ordered map is as follows:

om := orderedmap.New[string, string]()

To add a map entry is as follows:

om.Store("foo", "hoge")
prev, swapped := om.Swap("bar", "fuga")
actual, loaded := om.LoadOrStore("baz", "fuga")
actual, loaded, err := om.LoadOrStore("baz", func() (string, error) {
	return "fuga", nil
})

To get a value for a key is as follows:

om.Load("foo")

To delete a map entry is as follows:

om.Delete("bar")
v, deleted := om.LoadAndDelete("baz")

To delete a map entry logically is as follows:

om.Ldelete("bar")
v, deleted := om.LoadAndLdelete("baz")

To iterate map entries is as follows. The order is same with key insertions:

om.Range(func(k, v) bool {
    ...
})
for ent := om.Front(); ent != nil; ent = ent.Next() {
    k := ent.Key(); v : = ent.Value(); ...
}
for ent := om.Back(); ent != nil; ent = ent.Prev() {
    k := ent.Key(); v : = ent.Value(); ...
}

To serialize the public contents of this map into a JSON string is as follows:

byteSeq, e := om.MarshalJSON()

To deserialize a JSON string into an ordered map is as follows:

e := om.UnmarshalJSON(byteSeq)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Entry

type Entry[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Entry is a struct which is a map element and holds a pair of key and value. This struct also has methods: Next and Prev which moves next or previous entties sequencially.

func (*Entry[K, V]) Key

func (ent *Entry[K, V]) Key() K

Key is a method which returns the key of this entry.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")

	entry := om.Front()
	fmt.Printf("key = %v\n", entry.Key())
}
Output:

key = foo

func (*Entry[K, V]) Next

func (ent *Entry[K, V]) Next() *Entry[K, V]

Next is a method which returns the next entry of this entry. If this entry is a last entry of an ordered map, the returned value is nil.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.Front()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = entry.Next()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = entry.Next()
	fmt.Printf("entry = %v\n", entry)
}
Output:

key = foo, value = bar
key = baz, value = qux
entry = <nil>

func (*Entry[K, V]) Prev

func (ent *Entry[K, V]) Prev() *Entry[K, V]

Prev is a method which returns the previous entry of this entry. If this entry is a head entry of an ordered map, the returned value is nil.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.Back()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = entry.Prev()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = entry.Prev()
	fmt.Printf("entry = %v\n", entry)
}
Output:

key = baz, value = qux
key = foo, value = bar
entry = <nil>

func (*Entry[K, V]) Value

func (ent *Entry[K, V]) Value() V

Value is a method which returns the value of this entry.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")

	entry := om.Front()
	fmt.Printf("value = %v\n", entry.Value())
}
Output:

value = bar

type Map

type Map[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Map is a struct which represents a map similar with Go standard map, or sync.Map, but preserves the order in which keys were inserted.

This map has same methods with sync.Map except CompareAndDelete and CompareAndSwap. (But not support concurrent use.) Its Range method processes a key and a value of each map entry, and the processing order is same with the order of key insertions. And this map also has methods: Front and Back, which iterate this map entries in the order of key insertions and in that reverse order.

func New

func New[K comparable, V any]() Map[K, V]

New is a function which creates a new ordered map, which is ampty.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	fmt.Printf("om = %v\n", om)
}
Output:

om = Map[]

func (*Map[K, V]) Back

func (om *Map[K, V]) Back() *Entry[K, V]

Back is a method which returns the last entry of this map.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.Back()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
}
Output:

key = baz, value = qux

func (*Map[K, V]) BackAndDelete added in v0.4.0

func (om *Map[K, V]) BackAndDelete() *Entry[K, V]

BackAndDelete is a method which deletes the last entry and returns it. If this map has no entry, this method returns nil

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.BackAndDelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.BackAndDelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.BackAndDelete()
	fmt.Printf("entry = %v\n", entry)
	fmt.Printf("om = %v\n", om)
}
Output:

key = baz, value = qux
key = foo, value = bar
entry = <nil>
om = Map[]

func (*Map[K, V]) BackAndLdelete added in v0.4.0

func (om *Map[K, V]) BackAndLdelete() *Entry[K, V]

BackAndLdelete is a method which logically deletes the last entry and returns it. If this map has no entry, this method returns nil

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.BackAndLdelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.BackAndLdelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.BackAndLdelete()
	fmt.Printf("entry = %v\n", entry)
	fmt.Printf("om = %v\n", om)
}
Output:

key = baz, value = qux
key = foo, value = bar
entry = <nil>
om = Map[]

func (*Map[K, V]) Delete

func (om *Map[K, V]) Delete(key K)

Delete is a method which deletes a value for a key.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	om.Delete("foo")
	fmt.Printf("om = %v\n", om)
}
Output:

om = Map[baz:qux]

func (*Map[K, V]) Front

func (om *Map[K, V]) Front() *Entry[K, V]

Front is a method which returns the head entry of this map.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.Front()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
}
Output:

key = foo, value = bar

func (*Map[K, V]) FrontAndDelete added in v0.4.0

func (om *Map[K, V]) FrontAndDelete() *Entry[K, V]

FrontAndDelete is a method which deletes the first entry and returns it. If this map has no entry, this method returns nil

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.FrontAndDelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.FrontAndDelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.FrontAndDelete()
	fmt.Printf("entry = %v\n", entry)
	fmt.Printf("om = %v\n", om)
}
Output:

key = foo, value = bar
key = baz, value = qux
entry = <nil>
om = Map[]

func (*Map[K, V]) FrontAndLdelete added in v0.4.0

func (om *Map[K, V]) FrontAndLdelete() *Entry[K, V]

FrontAndLdelete is a method which logically deletes the first entry and returns it. If this map has no entry, this method returns nil

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	entry := om.FrontAndLdelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.FrontAndLdelete()
	fmt.Printf("key = %v, value = %v\n", entry.Key(), entry.Value())
	entry = om.FrontAndLdelete()
	fmt.Printf("entry = %v\n", entry)
	fmt.Printf("om = %v\n", om)
}
Output:

key = foo, value = bar
key = baz, value = qux
entry = <nil>
om = Map[]

func (*Map[K, V]) Ldelete

func (om *Map[K, V]) Ldelete(key K)

Ldelete is a method which logically deletes a value for a key.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	om.Ldelete("foo")
	fmt.Printf("om = %v\n", om)
}
Output:

om = Map[baz:qux]

func (*Map[K, V]) Len

func (om *Map[K, V]) Len() int

Len is a method which returns the number of entries in this map.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	fmt.Printf("orderedmap's length = %v\n", om.Len())
	om.Store("baz", "qux")
	fmt.Printf("orderedmap's length = %v\n", om.Len())
}
Output:

orderedmap's length = 1
orderedmap's length = 2

func (*Map[K, V]) Load

func (om *Map[K, V]) Load(key K) (value V, ok bool)

Load is a method which returns a value stored in this map for a key. If no value was found for a key, the ok result is false.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	value, ok := om.Load("foo")
	fmt.Printf("value = %v, ok = %t\n", value, ok)
	om.Store("foo", "bar")
	value, ok = om.Load("foo")
	fmt.Printf("value = %v, ok = %t\n", value, ok)
}
Output:

value = , ok = false
value = bar, ok = true

func (*Map[K, V]) LoadAndDelete

func (om *Map[K, V]) LoadAndDelete(key K) (value V, loaded bool)

LoadAndDelete is a method which deletes a value for a key, and returns the previous value if any. The loaded flag is true if the key was present.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	value, loaded := om.LoadAndDelete("foo")
	fmt.Printf("value = %v, loaded = %t\n", value, loaded)
	fmt.Printf("om = %v\n", om)
}
Output:

value = bar, loaded = true
om = Map[baz:qux]

func (*Map[K, V]) LoadAndLdelete

func (om *Map[K, V]) LoadAndLdelete(key K) (value V, loaded bool)

LoadAndLdelete is a method which logically deletes a value for a key, and returns the previous value if any. The loaded flag is true if the key was present.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	value, loaded := om.LoadAndLdelete("foo")
	fmt.Printf("value = %v, loaded = %t\n", value, loaded)
	fmt.Printf("om = %v\n", om)
}
Output:

value = bar, loaded = true
om = Map[baz:qux]

func (*Map[K, V]) LoadOrStore

func (om *Map[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool)

LoadOrStore is a method which returns a value for a key if presents, otherwise stores and returns a given value. The loaded flag is true if the value was loaded, false if stored.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	actual, loaded := om.LoadOrStore("foo", "bar")
	fmt.Printf("actual = %v, loaded = %t\n", actual, loaded)
	actual, loaded = om.LoadOrStore("foo", "BAZ")
	fmt.Printf("actual = %v, loaded = %t\n", actual, loaded)
}
Output:

actual = bar, loaded = false
actual = bar, loaded = true

func (*Map[K, V]) LoadOrStoreFunc

func (om *Map[K, V]) LoadOrStoreFunc(
	key K,
	fn func() (V, error),
) (actual V, loaded bool, err error)

LoadOrStoreFunc is a method which returns a value for a key if presents, otherwise executes a give function, then stores and returns the result value. The loaded flag is true if the value was loaded, false if stored.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	actual, loaded, err := om.LoadOrStoreFunc("foo", func() (string, error) {
		return "bar", nil
	})
	fmt.Printf("actual = %v, loaded = %t, err = %v\n", actual, loaded, err)
	actual, loaded, err = om.LoadOrStoreFunc("foo", func() (string, error) {
		return "BAZ", nil
	})
	fmt.Printf("actual = %v, loaded = %t, err = %v\n", actual, loaded, err)
}
Output:

actual = bar, loaded = false, err = <nil>
actual = bar, loaded = true, err = <nil>

func (Map[K, V]) MarshalJSON added in v0.5.0

func (om Map[K, V]) MarshalJSON() ([]byte, error)

MarshalJSON returns a byte array of JSON string which expresses the content of this map.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")

	b, e := om.MarshalJSON()
	fmt.Printf("json = %s\n", string(b))
	fmt.Printf("e = %v\n", e)
}
Output:

json = {"foo":"bar","baz":"qux"}
e = <nil>

func (*Map[K, V]) Range

func (om *Map[K, V]) Range(fn func(key K, value V) bool)

Range is a method which calls the specified function: fn sequentially for each key and value in this map. If fn returns false, this method stops the iteration.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")
	om.Store("quux", "corge")

	om.Range(func(key, value string) bool {
		fmt.Printf("key = %v, value = %v\n", key, value)
		if key == "baz" {
			return false
		}
		return true
	})
}
Output:

key = foo, value = bar
key = baz, value = qux

func (*Map[K, V]) Store

func (om *Map[K, V]) Store(key K, value V)

Store is a method which sets a value for a key

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	fmt.Printf("om = %v\n", om)
	om.Store("baz", "qux")
	fmt.Printf("om = %v\n", om)
}
Output:

om = Map[foo:bar]
om = Map[foo:bar baz:qux]

func (Map[K, V]) String added in v0.4.0

func (om Map[K, V]) String() string

String is a method which returns a string of the content of this map.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	om.Store("foo", "bar")
	om.Store("baz", "qux")
	fmt.Printf("om = %v\n", om)
}
Output:

om = Map[foo:bar baz:qux]

func (*Map[K, V]) Swap

func (om *Map[K, V]) Swap(key K, value V) (previous V, loaded bool)

Swap is a method which sets a value for a key. If the key was present, this map returns the previous value and the loaded flag which is set to true.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	prev, loaded := om.Swap("foo", "bar")
	fmt.Printf("prev = %v, loaded = %t\n", prev, loaded)
	prev, loaded = om.Swap("foo", "BAZ")
	fmt.Printf("prev = %v, loaded = %t\n", prev, loaded)
}
Output:

prev = , loaded = false
prev = bar, loaded = true

func (*Map[K, V]) UnmarshalJSON added in v0.5.0

func (om *Map[K, V]) UnmarshalJSON(data []byte) error

UnmarshalJSON sets the content of this map from a JSON data.

Example
package main

import (
	"fmt"

	"github.com/sttk/orderedmap"
)

func main() {
	om := orderedmap.New[string, string]()
	b := []byte(`{"foo":"bar","baz":"qux"}`)

	e := om.UnmarshalJSON(b)
	fmt.Printf("om = %v\n", om)
	fmt.Printf("e = %v\n", e)
}
Output:

om = Map[foo:bar baz:qux]
e = <nil>

type SyntaxError added in v0.5.0

type SyntaxError struct {
	Offset int64
	// contains filtered or unexported fields
}

SyntaxError is an error stype which is returned by Unmarshal when an input json does not start with "{" or end with "}", or there are value type mismatches.

func (SyntaxError) Error added in v0.5.0

func (err SyntaxError) Error() string

type UnsupportedKeyTypeError added in v0.5.0

type UnsupportedKeyTypeError struct {
	Type reflect.Type
}

UnsupportedTypeError is an error type which is returned by Marshal when attempting to encode an unsupported key type.

func (UnsupportedKeyTypeError) Error added in v0.5.0

func (err UnsupportedKeyTypeError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL