README
¶
Ordered Map
ordmap
is a Go package that provides a generic ordered map implementation, primarily designed for JSON v2 marshalling and unmarshalling using the go-json-experiment library.
An ordered map maintains the order of keys based on insertion, allowing you to iterate over the map in the order in which entries were added. This can be particularly useful for applications where the order of elements is important, such as in JSON serialization or when maintaining the sequence of operations.
Features
- Seamless JSON v2 Integration: Directly integrates with the JSON v2 library for efficient and order-preserving marshalling and unmarshalling.
- Custom Ordered Maps: Provides robust helper functions to easily define your own custom ordered maps with minimal boilerplate code.
- Pre-Defined Ordered Map Alias: Simplifies usage by offering a pre-defined ordered map type that can be conveniently aliased for specific key and value types.
- Efficient Ordered Operations: Ensures efficient insertion, retrieval, and iteration while maintaining the order of elements, making it ideal for use cases where order matters.
- Ordered Iteration: Leverages the
ByIndex
method to iterate over the map in an ordered manner based on the insertion sequence.
Installation
To install the library, use the following command:
go get github.com/MarkRosemaker/ordmap
Usage
Custom Ordered Map
To create your own custom ordered map, you can utilize helper functions to define its methods:
package main
import (
"iter"
"github.com/MarkRosemaker/ordmap"
"github.com/go-json-experiment/json"
"github.com/go-json-experiment/json/jsontext"
)
type MyOrderedMap map[string]*ValueWithIndex
type ValueWithIndex struct {
Foo string `json:"foo"`
Bar int `json:"bar"`
idx int // to order a map of this type
}
func getIndex(v *ValueWithIndex) int { return v.idx }
func setIndex(v *ValueWithIndex, i int) *ValueWithIndex { v.idx = i; return v }
// ByIndex returns a sequence of key-value pairs ordered by index.
func (om MyOrderedMap) ByIndex() iter.Seq2[string, *ValueWithIndex] {
return ordmap.ByIndex(om, getIndex)
}
// Sort sorts the map by key and sets the indices accordingly.
func (om MyOrderedMap) Sort() {
ordmap.Sort(om, setIndex)
}
// Set sets a value in the map, adding it at the end of the order.
func (om *MyOrderedMap) Set(key string, v *ValueWithIndex) {
ordmap.Set(om, key, v, getIndex, setIndex)
}
// MarshalJSONTo marshals the key-value pairs in order.
func (om *MyOrderedMap) MarshalJSONTo(enc *jsontext.Encoder, opts json.Options) error {
return ordmap.MarshalJSONTo(om, enc, opts)
}
// UnmarshalJSONFrom unmarshals the key-value pairs in order and sets the indices.
func (om *MyOrderedMap) UnmarshalJSONFrom(dec *jsontext.Decoder, opts json.Options) error {
return ordmap.UnmarshalJSONFrom(om, dec, opts, setIndex)
}
If you prefer the map values to be non-pointer types, you can adjust the implementation as follows:
type MyOrderedMap map[string]ValueWithIndex
func getIndex(v ValueWithIndex) int { return v.idx }
func setIndex(v ValueWithIndex, i int) ValueWithIndex { v.idx = i; return v }
func (om MyOrderedMap) ByIndex() iter.Seq2[string, ValueWithIndex] {
return ordmap.ByIndex(om, getIndex)
}
func (om *MyOrderedMap) Set(key string, v ValueWithIndex) {
ordmap.Set(om, key, v, getIndex, setIndex)
}
Using The Pre-Defined Ordered Map
For simplicity, an ordered map type is already defined for you. You only need to specify the key and value types:
package main
import (
"github.com/MarkRosemaker/ordmap"
)
type MyOrderedMap = ordmap.OrderedMap[string, *MyValue]
type MyValue struct {
Foo string `json:"foo"`
Bar int `json:"bar"`
}
Contributing
If you have any contributions to make, please submit a pull request or open an issue on the GitHub repository.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Documentation
¶
Index ¶
- func ByIndex[M ~map[K]V, K comparable, V any](m M, getIndex func(V) int) iter.Seq2[K, V]
- func MarshalJSONTo[M ByIndexer[K, V], K comparable, V any](m M, enc *jsontext.Encoder, opts json.Options) error
- func Set[M ~map[K]V, K comparable, V any](m *M, key K, v V, getIndex func(V) int, setIndex func(V, int) V)
- func Sort[M ~map[K]V, K cmp.Ordered, V any](m M, setIndex func(V, int) V)
- func SortFunc[M ~map[K]V, K comparable, V any](m M, setIndex func(V, int) V, less func(K, K) int)
- func UnmarshalJSONFrom[M ~map[K]R, K comparable, R any](m *M, dec *jsontext.Decoder, opts json.Options, setIndex func(R, int) R) error
- type ByIndexer
- type OrderedMap
- func (om OrderedMap[K, V]) ByIndex() iter.Seq2[K, V]
- func (om *OrderedMap[_, _]) MarshalJSONTo(enc *jsontext.Encoder, opts json.Options) error
- func (om *OrderedMap[K, V]) Set(key K, v V)
- func (om OrderedMap[K, V]) Sort(less func(K, K) int)
- func (om *OrderedMap[K, V]) UnmarshalJSONFrom(dec *jsontext.Decoder, opts json.Options) error
- type Value
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ByIndex ¶
func ByIndex[M ~map[K]V, K comparable, V any](m M, getIndex func(V) int) iter.Seq2[K, V]
ByIndex is a helper function for an ordered map to implement an iterator.
func MarshalJSONTo ¶
func MarshalJSONTo[M ByIndexer[K, V], K comparable, V any]( m M, enc *jsontext.Encoder, opts json.Options, ) error
MarshalJSONTo marshals an ordered map by encoding its key-value pairs in order.
func Set ¶
func Set[M ~map[K]V, K comparable, V any]( m *M, key K, v V, getIndex func(V) int, setIndex func(V, int) V, )
Set is a helper function to set a value in the map, adding it at the end of the order.
func SortFunc ¶
func SortFunc[M ~map[K]V, K comparable, V any](m M, setIndex func(V, int) V, less func(K, K) int)
SortFunc is a helper function to sort a map by key using a custom comparison function and set the indices accordingly.
func UnmarshalJSONFrom ¶
func UnmarshalJSONFrom[M ~map[K]R, K comparable, R any]( m *M, dec *jsontext.Decoder, opts json.Options, setIndex func(R, int) R, ) error
UnmarshalJSONFrom is a helper function to unmarshal an ordered map setting the indices in order.
Types ¶
type ByIndexer ¶
type ByIndexer[K comparable, V any] interface { // ByIndex returns a sequence of key-value pairs sorted by index. ByIndex() iter.Seq2[K, V] }
ByIndexer is an interface for an ordered map that implements an iterator.
type OrderedMap ¶
type OrderedMap[K comparable, V any] map[K]Value[V]
OrderedMap is a map that can be ordered.
func (OrderedMap[K, V]) ByIndex ¶
func (om OrderedMap[K, V]) ByIndex() iter.Seq2[K, V]
ByIndex returns a sequence of key-value pairs sorted by index.
func (*OrderedMap[_, _]) MarshalJSONTo ¶
MarshalJSONTo marshals the key-value pairs in order.
func (*OrderedMap[K, V]) Set ¶
func (om *OrderedMap[K, V]) Set(key K, v V)
Set sets a value in the map, adding it at the end of the order.
func (OrderedMap[K, V]) Sort ¶
func (om OrderedMap[K, V]) Sort(less func(K, K) int)
Sort sorts the map by key using a custom comparison function and sets the indices accordingly.
func (*OrderedMap[K, V]) UnmarshalJSONFrom ¶
UnmarshalJSONFrom unmarshals the key-value pairs in order and sets the indices.
type Value ¶
type Value[V any] struct { V V // contains filtered or unexported fields }
Value is a value with an index.
func (Value[_]) MarshalJSONTo ¶
MarshalJSONTo marshals a value by encoding just the value and ignoring the index.