jsonmap

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 2, 2023 License: MIT Imports: 3 Imported by: 5

README

Ordered map

go test workflow

Simple ordered map for Go, with JSON restrictions. The main purpose is to keep same order of keys after parsing JSON and generating it again, so Unmarshal followed by Marshal generates exactly the same JSON structure

Keys are strings, Values are any JSON values (number, string, boolean, null, array, map/object)

Storage is O(N), operations are O(1), except Delete, which is O(N) time. Delete can be reimplemented in O(log(N)) time with additional O(N) storage, or in O(1) time with more complicated data structures, but let's keep it simple for now

When Unmarshalling, any nested map from JSON is created as ordered, including maps in nested arrays

Inspired by https://github.com/iancoleman/orderedmap

Usage

package main

import (
	"encoding/json"
	"fmt"

	"github.com/metalim/jsonmap"
)

const input = `{"an":"article","empty":null,"sub":{"x":1,"y":2},"bool":false,"array":[1,2,3]}`

func main() {
	m := jsonmap.New()

	// unmarshal, keeping order
	err := json.Unmarshal([]byte(input), &m)
	if err != nil {
		panic(err)
	}

	fmt.Println(m.Keys())         // [an empty sub bool array]
	fmt.Println(m.Get("an"))      // article true
	fmt.Println(m.Get("nothing")) // <nil> false

	// marshal, keeping order
	output, err := json.Marshal(&m)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(output) == input) // true

	// set new values, keeping order of existing keys
	m.Set("an", "bar")
	m.Set("truth", true)
	fmt.Println(m.Keys()) // [an empty sub bool array truth]

	// delete key "sub"
	m.Delete("sub")
	fmt.Println(m.Keys()) // [an empty bool array truth]

	// update value for key "an", and move it to the end
	m.Push("an", false)
	fmt.Println(m.Keys()) // [empty bool array truth an]

	data, err := json.Marshal(&m)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(data)) // {"empty":null,"bool":false,"array":[1,2,3],"truth":true,"an":false}
}

Alternatives

Let me know of other alternatives, I'll add them here

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Key

type Key = string

type Map

type Map struct {
	// contains filtered or unexported fields
}

func New

func New() *Map

func (*Map) Delete

func (m *Map) Delete(key string)

func (*Map) Get

func (m *Map) Get(key string) (value any, ok bool)

func (*Map) IndexKey

func (m *Map) IndexKey(key string) int

with additional O(n) memory this can be done in O(log n) via binary search, or even O(1) via more advanced data structures. But lets keep it simple for now

func (*Map) Keys

func (m *Map) Keys() []string

func (*Map) Len

func (m *Map) Len() int

func (*Map) MarshalJSON

func (m *Map) MarshalJSON() ([]byte, error)

func (*Map) Push

func (m *Map) Push(key Key, value Value)

Same as Set, but pushes the key to the end

func (*Map) Set

func (m *Map) Set(key Key, value Value)

func (*Map) UnmarshalJSON

func (m *Map) UnmarshalJSON(data []byte) error

type Value

type Value = any

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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