orderedjson

package module
v0.0.1-beta.1 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2019 License: MIT Imports: 6 Imported by: 0

README

ordered-json

A fork of the https://gitlab.com/c0b/go-ordered-json package to support atomic access

Documentation

Overview

Package ordered provided a type OrderedMap for use in JSON handling although JSON spec says the keys order of an object should not matter but sometimes when working with particular third-party proprietary code which has incorrect using the keys order, we have to maintain the object keys in the same order of incoming JSON object, this package is useful for these cases.

Disclaimer: same as Go's default [map](https://blog.golang.org/go-maps-in-action)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type KVPair

type KVPair struct {
	Key   string
	Value interface{}
}

the key-value pair type, for initializing from a list of key-value pairs, or for looping entries in the same order

type OrderedMap

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

the OrderedMap type, has similar operations as the default map, but maintained the keys order of inserted; similar to map, all single key operations (Get/Set/Delete) runs at O(1).

func NewOrderedMap

func NewOrderedMap() *OrderedMap

Create a new OrderedMap

func NewOrderedMapFromKVPairs

func NewOrderedMapFromKVPairs(pairs []*KVPair) *OrderedMap

Create a new OrderedMap and populate from a list of key-value pairs

func (*OrderedMap) Delete

func (om *OrderedMap) Delete(key string) (value interface{}, ok bool)

deletes the element with the specified key (m[key]) from the map. If there is no such element, this is a no-op.

func (*OrderedMap) EntriesIter

func (om *OrderedMap) EntriesIter() func() (*KVPair, bool)

Iterate all key/value pairs in the same order of object constructed

func (*OrderedMap) EntriesReverseIter

func (om *OrderedMap) EntriesReverseIter() func() (*KVPair, bool)

Iterate all key/value pairs in the reverse order of object constructed

Example
// initialize from a list of key-value pairs
om := NewOrderedMapFromKVPairs([]*KVPair{
	{"country", "United States"},
	{"countryCode", "US"},
	{"region", "CA"},
	{"regionName", "California"},
	{"city", "Mountain View"},
	{"zip", "94043"},
	{"lat", 37.4192},
	{"lon", -122.0574},
	{"timezone", "America/Los_Angeles"},
	{"isp", "Google Cloud"},
	{"org", "Google Cloud"},
	{"as", "AS15169 Google Inc."},
	{"mobile", true},
	{"proxy", false},
	{"query", "35.192.xx.xxx"},
})

iter := om.EntriesReverseIter()
for {
	pair, ok := iter()
	if !ok {
		break
	}
	fmt.Printf("%-12s: %v\n", pair.Key, pair.Value)
}
Output:

query       : 35.192.xx.xxx
proxy       : false
mobile      : true
as          : AS15169 Google Inc.
org         : Google Cloud
isp         : Google Cloud
timezone    : America/Los_Angeles
lon         : -122.0574
lat         : 37.4192
zip         : 94043
city        : Mountain View
regionName  : California
region      : CA
countryCode : US
country     : United States

func (*OrderedMap) Get

func (om *OrderedMap) Get(key string) interface{}

Get value for particular key, or nil if not exist; but don't rely on nil for non-exist; should check by Has or GetValue

func (*OrderedMap) GetMap

func (om *OrderedMap) GetMap() map[string]interface{}

get map

func (*OrderedMap) GetValue

func (om *OrderedMap) GetValue(key string) (value interface{}, ok bool)

Get value and exists together

func (*OrderedMap) Has

func (om *OrderedMap) Has(key string) bool

Check if value exists

func (*OrderedMap) MarshalJSON

func (om *OrderedMap) MarshalJSON() (res []byte, err error)

this implements type json.Marshaler interface, so can be called in json.Marshal(om)

func (*OrderedMap) Set

func (om *OrderedMap) Set(key string, value interface{})

set value for particular key, this will remember the order of keys inserted but if the key already exists, the order is not updated.

func (*OrderedMap) UnmarshalJSON

func (om *OrderedMap) UnmarshalJSON(data []byte) error

this implements type json.Unmarshaler interface, so can be called in json.Unmarshal(data, om)

Example
const jsonStream = `{
  "country"     : "United States",
  "countryCode" : "US",
  "region"      : "CA",
  "regionName"  : "California",
  "city"        : "Mountain View",
  "zip"         : "94043",
  "lat"         : 37.4192,
  "lon"         : -122.0574,
  "timezone"    : "America/Los_Angeles",
  "isp"         : "Google Cloud",
  "org"         : "Google Cloud",
  "as"          : "AS15169 Google Inc.",
  "mobile"      : true,
  "proxy"       : false,
  "query"       : "35.192.xx.xxx"
}`

// compare with if using a regular generic map, the unmarshalled result
//  is a map with unpredictable order of keys
var m map[string]interface{}
err := json.Unmarshal([]byte(jsonStream), &m)
if err != nil {
	fmt.Println("error:", err)
}
for key := range m {
	// fmt.Printf("%-12s: %v\n", key, m[key])
	_ = key
}

// use the OrderedMap to Unmarshal from JSON object
var om *OrderedMap = NewOrderedMap()
err = json.Unmarshal([]byte(jsonStream), om)
if err != nil {
	fmt.Println("error:", err)
}

// use an iterator func to loop over all key-value pairs,
// it is ok to call Set append-modify new key-value pairs,
// but not safe to call Delete during iteration.
iter := om.EntriesIter()
for {
	pair, ok := iter()
	if !ok {
		break
	}
	fmt.Printf("%-12s: %v\n", pair.Key, pair.Value)
	if pair.Key == "city" {
		om.Set("mobile", false)
		om.Set("extra", 42)
	}
}
Output:

country     : United States
countryCode : US
region      : CA
regionName  : California
city        : Mountain View
zip         : 94043
lat         : 37.4192
lon         : -122.0574
timezone    : America/Los_Angeles
isp         : Google Cloud
org         : Google Cloud
as          : AS15169 Google Inc.
mobile      : false
proxy       : false
query       : 35.192.xx.xxx
extra       : 42

Jump to

Keyboard shortcuts

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