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

Overview

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!

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

    opened by water-a 11
  • 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?

    enhancement help wanted 
    opened by cretz 8
  • 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.

    opened by leighmcculloch 8
  • 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

    4. to release 
    opened by geseq 7
  • 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, "...") 
    
    bug 
    opened by an2deg 7
  • 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}}
    
    bug 
    opened by PeerXu 5
  • 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)
    4. to release dependencies go 
    opened by dependabot[bot] 4
  • 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
    4. to release 
    opened by geseq 3
  • 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
    4. to release 
    opened by geseq 3
  • 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.

    4. to release 
    opened by geseq 3
  • .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.

    opened by nelsam 3
  • 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

    opened by Thiht 0
  • Use go1.13; remove vendor folder; update .github action

    Use go1.13; remove vendor folder; update .github action

    Summary

    This PR:

    • updates go.mod to use go 1.13
    • removes vendor folder, and changes README
    • changes go versions in .github actions to be the same as in the https://github.com/stretchr/testify.

    Checklist

    • [x] Tests are passing: task test
    • [x] Code style is correct: task lint
    opened by alexandear 0
  • 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.

    opened by kaovilai 8
  • 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.

    help wanted 
    opened by hanzei 4
Releases(v0.5.0)
  • v0.5.0(Oct 15, 2022)

  • v0.4.0(May 8, 2022)

    • 6c797d8 Add helpers for slice of Map (#102)
    • 8dffac51 add github action (#106)
    • 31052d3 fix cc test reporter (#107)
    • 0ea374a fix nested array access (#104)
    • 4ff3852e fix int to float conversions (#108)
    • 27373ce fix set within Map child element (#105)
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Jul 15, 2020)

  • v0.2.0(Apr 9, 2019)

    Notes

    This release drops the support for go version less then 1.10.

    Enhancements

    • ea4fe68 Move to go modules (#91)
    • d2ce263 Update to go 1.12 (#90)
    • ef50b0d Update to go 1.11 (#83)
    • d0444fc Update dependencies (#82)
    • b8b73a3 URLQuery with index slice keys (#74)
    • 9e1dfc1 Update dependencies (#81)
    • 0ab728f New tests for type_specific.go and fixed code (#75)
    • 652affc Add PULL_REQUEST_TEMPLATE.md (#77)
    • c8db58a Move type Map out of type_specific_codegen.go (#73)
    • fb88214 URLValues without sprinf, support for maps and slices (#63)
    • a5cfa15 Add go 1.10 tests && update dependencies (#67)
    • 2b6f327 When calling Set() with key pointing to nonexistent map path, the path will be created. (#66)
    • ca93b98 Convert floats to int when parsing JSON (#59)
    • 3f41636 Move tests to objx_test (#58)
    • fcc2171 Remove constants file (#57)
    • cfebd64 Codeclimate (#54)
    • 84b0369 Refactor accessors (#53)

    Fixes

    • c61a9df Fix for map[interface{}]interface{} to JSON conversion (#87)
    • d3a9fb1 Fix for #7 (#85)
    • 77d0150 Nil value returns empty string. (#76)
    • a97c7cc Fixed incorrect result for obj.Value().MSI() getter (#65)
    • 2532633 Fix indentation (#69)
    • 8a3f715 Fix bug introduced with #17 (#60)
    • e89b2c1 Fix ObjxMapSlice (#17)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.1(Jun 10, 2018)

    Changelog

    Enhancements

    • func MSI(keyAndValuePairs ...interface{}) Map does not longer panik, when called with wrong arguments

    Fixes

    • Added tests
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Jun 26, 2018)

Owner
Stretchr, Inc.
Tame your unstructured data - We <3 open-source.
Stretchr, Inc.
generic sort for slices in golang

slices generic sort for slices in golang basic API func BinarySearch[E constraints.Ordered](list []E, x E) int func IsSorted[E constraints.Ordered](li

阮坤良 17 Nov 3, 2022
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

Ondřej Merkun 12 Sep 17, 2021
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

Ugorji Nwoke 1.7k Nov 17, 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

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

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

Jsoniter 11.5k Nov 23, 2022
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

Vladislav Fursov 62 Nov 6, 2022
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

Wei Shen 7 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

Jason E. Aten, Ph.D. 286 Nov 29, 2022
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

Jacek Szwec 766 Nov 21, 2022
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

Joel Ling 7 Oct 13, 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

null 0 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

Logicalis 53 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

Mitchell Hashimoto 6.4k Dec 2, 2022
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

Mitchell Hashimoto 171 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

Ren 37 Oct 4, 2022
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

null 26 Oct 27, 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

Elliot Chance 1.2k Nov 25, 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

null 0 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

null 4 Aug 26, 2022