Go package for dealing with maps, slices, JSON and other data.

Objx

Build Status Go Report Card Maintainability Test Coverage Sourcegraph GoDoc

Objx - Go package for dealing with maps, slices, JSON and other data.

Get started:

Overview

Objx provides the objx.Map type, which is a map[string]interface{} that exposes a powerful Get method (among others) that allows you to easily and quickly get access to data within the map, without having to worry too much about type assertions, missing data, default values etc.

Pattern

Objx uses a preditable pattern to make access data from within map[string]interface{} easy. Call one of the objx. functions to create your objx.Map to get going:

m, err := objx.FromJSON(json)

NOTE: Any methods or functions with the Must prefix will panic if something goes wrong, the rest will be optimistic and try to figure things out without panicking.

Use Get to access the value you're interested in. You can use dot and array notation too:

 m.Get("places[0].latlng")

Once you have sought the Value you're interested in, you can use the Is* methods to determine its type.

 if m.Get("code").IsStr() { // Your code... }

Or you can just assume the type, and use one of the strong type methods to extract the real value:

m.Get("code").Int()

If there's no value there (or if it's the wrong type) then a default value will be returned, or you can be explicit about the default value.

 Get("code").Int(-1)

If you're dealing with a slice of data as a value, Objx provides many useful methods for iterating, manipulating and selecting that data. You can find out more by exploring the index below.

Reading data

A simple example of how to use Objx:

// Use MustFromJSON to make an objx.Map from some JSON
m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)

// Get the details
name := m.Get("name").Str()
age := m.Get("age").Int()

// Get their nickname (or use their name if they don't have one)
nickname := m.Get("nickname").Str(name)

Ranging

Since objx.Map is a map[string]interface{} you can treat it as such. For example, to range the data, do what you would expect:

m := objx.MustFromJSON(json)
for key, value := range m {
  // Your code...
}

Installation

To install Objx, use go get:

go get github.com/stretchr/objx

Staying up to date

To update Objx to the latest version, run:

go get -u github.com/stretchr/objx

Supported go versions

We support the lastest three major Go versions, which are 1.10, 1.11 and 1.12 at the moment.

Contributing

Please feel free to submit issues, fork the repository and send pull requests!

Owner
Stretchr, Inc.
Tame your unstructured data - We <3 open-source.
Stretchr, Inc.
Comments
  • Slices not being handled correctly...

    Slices not being handled correctly...

    package main
    
    import (
    	"github.com/stretchr/objx"
    	"log"
    	"reflect"
    )
    
    func main() {
    	m := objx.MustFromJSON(`{"a":{"b":["hello"]}}`)
    	v := m.Get("a.b")
    	
    	log.Println(reflect.TypeOf(v.Data())) // []interface{}
    	log.Println(v.IsStrSlice()) // false
    	log.Println(v.StringSlice()) 
        // got: empty string slice: []string{}
        // expected: []string{"hello"}
    }
    

    Go version: go version go1.19 darwin/arm64

    Simple example where I'm trying to retrieve the array "a.b" and retrieve it as a string slice, but it returns an empty string array

  • Unable to select map key with dot

    Unable to select map key with dot

    If I have a map where the keys may be domain names and the values are some object, how do I select a field on the value for key "google.com" via Get?

  • Tag v0.1 as v0.1.0

    Tag v0.1 as v0.1.0

    vgo requires that versions have three parts, like v0.1.0, but the only version tagged for objx is v0.1, and so vgo is unable to use that version. Could you please add a tag at the same commit as v0.1, and name it v0.1.0?

    You can do this by:

    git tag -a v0.1.0 v0.1
    git push origin v0.1.0
    

    This is required to close stretchr/testify#607.

  • URLQuery with index slice keys

    URLQuery with index slice keys

    Certain APIs (I believe those written in PHP) seem to be unable to parse correctly URLQuery() result containing slices generated by URLValuesSliceKeySuffix="" or URLValuesSliceKeySuffix="[]".

    The solution is to pass the slices with an index so that they are read correctly.

    For instance, in order to parse slices of the form correctly: objx.Map{"mapSlice": []objx.Map{objx.Map{"age": 40, "sex": "male"}, objx.Map{"height": 152}}} the query needs to be: mapSlice[0][age]=40&mapSlice[0][sex]=male&mapSlice[1][height]=152

    Currently these two forms are possible which don't work: mapSlice[age]=40&mapSlice[sex]=male&mapSlice[height]=152 mapSlice[][age]=40&mapSlice[][sex]=male&mapSlice[][height]=152

    I've modified the code to check for URLValuesSliceKeySuffix="[i]" and use slice indexes when present

  • Panic on MustInt()

    Panic on MustInt()

    Hi!

    I have the following JSON structure:

    {"d":[{"author":{"displayName":"DemoUser3","id":2},"classes":null,"id":9879,"v":{"code":"","created":"2013-09-19T09:38:50+02:00","published":"0001-01-01T00:00:00Z","updated":"2013-09-19T09:38:50+02:00"}}],"s":200}
    

    Objx panics on json.Get("d[0].id").Int(). Test:

        json, err := objx.FromJSON(`{"d":[{"author":{"displayName":"DemoUser3","id":2},"classes":null,"id":9879,"v":{"code":"","created":"2013-09-19T09:38:50+02:00","published":"0001-01-01T00:00:00Z","updated":"2013-09-19T09:38:50+02:00"}}],"s":200}`)
    
        if !assert.NoError(t, err, "Can't decode output") {
            return
        }
    
        assert.Equal(t, json.Get("d[0].id").Int(), 9879, "...") 
    
  • Set operator with not expected behavior

    Set operator with not expected behavior

    create map by FromJSON or New(with map[string]interface{}), and Set with fields got the difference result.

    m := objx.FromJSON(`{"a": {"b": 1}}`)
    m.Set("a.c", 2)
    fmt.Println(m.JSON())  // output: {"a": {"c": 2}}
    
    m := objx.New(map[string]interface{}{
      "a": map[string]interface{}{
        "b": 1,
      },
    })
    m.Set("a.c", 2)
    fmt.Println(m.JSON())  // output: {"a": {"b": 1, "c": 2}}
    
  • Bump github.com/stretchr/testify from 1.7.1 to 1.8.0

    Bump github.com/stretchr/testify from 1.7.1 to 1.8.0

    Bumps github.com/stretchr/testify from 1.7.1 to 1.8.0.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • fix cc test reporter

    fix cc test reporter

    fixes the cc-test-reporter failure in GitHub workflow

    Summary

    Checklist

    [Place an '[x]' (no spaces) in all applicable fields. Please remove unrelated fields.]

    • [x] Tests are passing: task test
    • [x] Code style is correct: task lint
  • fix set within Map child element

    fix set within Map child element

    Summary

    closes https://github.com/stretchr/objx/issues/97

    Fixes Set call when trying to set a value into an inner element that's a Map type as described in https://github.com/stretchr/objx/issues/97

    Checklist

    • [x] Tests are passing: task test
    • [x] Code style is correct: task lint
  • Fix for map[interface{}]interface{} to JSON conversion

    Fix for map[interface{}]interface{} to JSON conversion

    If map[interface{}]interface{} end up within the Map, JSON() and MustJSON() fail even if the data is valid. Added methods to cleanup the data before converting to JSON.

  • .Each(...) for MSI values

    .Each(...) for MSI values

    As it stands, Value.Each only works for slices; either a Map.Each or Value.MSIEach that accepts a function (e.g. func(key string, value interface{}) bool) would be nice.

    Although, I have an aversion to MSIEach just because it has "MSIE" in it. But that's just me.

  • Differentiate nil from not found

    Differentiate nil from not found

    Hi, objx doesn't make a distinction between keys not existing and keys set to nil: https://go.dev/play/p/UAcl_8eT_BI

    Is there an existing way to make the distinction that I've missed? Otherwise I'll be happy to submit a patch

  • Circular dependency with testify

    Circular dependency with testify

    objx requires github.com/stretchr/testify v1.7.1 github.com/stretchr/testify requires objx v0.4.0

    Would be cool if it could be avoided. No other reason in particular.

  • Looking for maintainers

    Looking for maintainers

    I don't have the time to maintain this library any longer. Are there people interested in maintaining this library?

    The main tasks for the near future is to revisit the API for this library and push this to v1.0.

Helper functions for the manipulation of slices of all types in Go

go-slices Unlike many other programming languages, Go doesn't provide helper functions for slices in it's core. I felt like this was quite an essentia

Jan 3, 2023
Easily and dynamically generate maps from Go static structures

structomap This package helps you to transform your struct into map easily. It provides a structomap.Serializer interface implemented by the structoma

Dec 9, 2022
idiomatic codec and rpc lib for msgpack, cbor, json, etc. msgpack.org[Go]

go-codec This repository contains the go-codec library, the codecgen tool and benchmarks for comparing against other libraries. This is a High Perform

Dec 19, 2022
Generate TypeScript interfaces from Go structs/interfaces - useful for JSON RPC

bel Generate TypeScript interfaces from Go structs/interfaces - useful for JSON RPC bel is used in production in https://gitpod.io. Getting started be

Oct 23, 2022
A high-performance 100% compatible drop-in replacement of "encoding/json"
A high-performance 100% compatible drop-in replacement of

A high-performance 100% compatible drop-in replacement of "encoding/json" You can also use thrift like JSON using thrift-iterator Benchmark Source cod

Jan 7, 2023
Golang binary decoder for mapping data into the structure

binstruct Golang binary decoder to structure Install go get -u github.com/ghostiam/binstruct Examples ZIP decoder PNG decoder Use For struct From file

Dec 17, 2022
A k-mer serialization package for Golang
A k-mer serialization package for Golang

.uniq v5 This package provides k-mer serialization methods for the package kmers, TaxIds of k-mers are optionally saved, while there's no frequency in

Aug 19, 2022
Cap'n Proto library and parser for go. This is go-capnproto-1.0, and does not have rpc. See https://github.com/zombiezen/go-capnproto2 for 2.0 which has rpc and capabilities.

Version 1.0 vs 2.0 Update 2015 Sept 20: Big news! Version 2.0 of the go-bindings, authored by Ross Light, is now released and newly available! It feat

Nov 29, 2022
csvutil provides fast and idiomatic mapping between CSV and Go (golang) values.
csvutil provides fast and idiomatic mapping between CSV and Go (golang) values.

csvutil Package csvutil provides fast and idiomatic mapping between CSV and Go (golang) values. This package does not provide a CSV parser itself, it

Jan 6, 2023
Encode and decode binary message and file formats in Go

Encode and Decode Binary Formats in Go This module wraps the package encoding/binary of the Go standard library and provides the missing Marshal() and

Dec 22, 2022
Some Golang types based on builtin. Implements interfaces Value / Scan and MarshalJSON / UnmarshalJSON for simple working with database NULL-values and Base64 encoding / decoding.

gotypes Some simple types based on builtin Golang types that implement interfaces for working with DB (Scan / Value) and JSON (Marshal / Unmarshal). N

Feb 12, 2022
Asn.1 BER and DER encoding library for golang.

WARNING This repo has been archived! NO further developement will be made in the foreseen future. asn1 -- import "github.com/PromonLogicalis/asn1" Pac

Nov 14, 2022
Go library for decoding generic map values into native Go structures and vice versa.

mapstructure mapstructure is a Go library for decoding generic map values to structures and vice versa, while providing helpful error handling. This l

Jan 1, 2023
Encode and decode Go (golang) struct types via protocol buffers.

protostructure protostructure is a Go library for encoding and decoding a struct type over the wire. This library is useful when you want to send arbi

Nov 15, 2022
Simple, specialised, and efficient binary marshaling

?? surge Documentation A library for fast binary (un)marshaling. Designed to be used in Byzantine networks, ?? surge never explicitly panics, protects

Oct 4, 2022
An optimal, byte-aligned, LZ+RLE hybrid encoder, designed to maximize decoding speed on NMOS 6502 and derived CPUs
An optimal, byte-aligned, LZ+RLE hybrid encoder, designed to maximize decoding speed on NMOS 6502 and derived CPUs

TSCrunch TSCrunch is an optimal, byte-aligned, LZ+RLE hybrid encoder, designed to maximize decoding speed on NMOS 6502 and derived CPUs, while keeping

Dec 21, 2022
🍕 Enjoy a slice! A utility library for dealing with slices and maps that focuses on type safety and performance.

?? github.com/elliotchance/pie Enjoy a slice! pie is a library of utility functions for common operations on slices and maps. Quick Start FAQ What are

Dec 30, 2022
Tutorial code for my video Learn to Use Basic Data Structures - Slices, Structs and Maps in Golang

Learn to Use Basic Data Structures - Slices, Structs and Maps in Golang Read text from a file and split into words. Introduction to slices / lists. Co

Jan 26, 2022
A Go package for checking conditions for slices and maps.

check Go package The check package of Go helps one to check various conditions for slices: []int []float64 []string []bool maps: map[string]int map[st

Aug 26, 2022