failed to json.marshal map with non string keys - json

I want to convert a map[int]string to json, so I thought json.Marshal() would do the trick, but it fails saying unsupported type map[int]string. But whereas if I use a map with key string it works fine.
http://play.golang.org/p/qhlS9Nt8qQ
Later on inspection of the marshaller code, there is an explicit check to see if the key is not string and returns UnsupportedTypeError...
Why can't I even use primitives as keys? If json standard doesn't allow non string keys, shouldn't json.Marshal convert the primitives to string and use them as keys ?

It's not because of Go, but because of Json: Json does not support anything else than strings for keys.
Have a look a the grammar of Json:
pair
string : value
string
""
" chars "
The full grammar is available on the Json website.
Unfortunately, to use integers as keys, you must convert them to string beforehand, for instance using strconv.Itoa: it is not up to the json package to do this work.

Related

Convert inconsistently formatted JSON String to Object

I'm having the below JSON coming in as a String input to my code. Since the string isn't uniformly formatted, overcoming the escape characters and grouping of the quotes to read the string and convert it into Java Object and sub-objects has run into issues
{"payload":{"details":"{\"source\":\"incor\",\"type\":\"build\",\"created\":\"1553855543108\",\"organization\":null,\"project\":null,\"application\":null,\"_content_id\":null,\"attributes\":null,\"requestHeaders\":{}}","content":"{\"project\":{\"name\":\"spinner\",\"lastBuild\":{\"building\":false,\"number\":0}},\"master\":\"IncorHealthCheck\"}","rawContent":null,"eventId":"bb357b79-069b-426d-8d21-8d04b06f5009"},"eventName":"city_spinner_events"}
I've tried using GSON, Jackson so far to try and read the String and convert into object and sub-objects. However, I've been able to objectify only the top level object. I face issues while I need to create sub-objects due to the escape characters and misreading of grouping of quotes by the parser. It throws errors and exceptions.
The expected JSON is as below which can be converted to object :
{"payload":{"details":{"source":"incor","type":"build","created":"1553855543108","organization":null,"project":null,"application":null,"_content_id":null,"attributes":null,"requestHeaders":{}},"content":{"project":{"name":"spinner","lastBuild":{"building":false,"number":0}},"master":"IncorHealthCheck"},"rawContent":null,"eventId":"bb357b79-069b-426d-8d21-8d04b06f5009"},"eventName":"city_spinner_events"}
Try unescapeJava from org.apache.commons.text.StringEscapeUtils,
StringEscapeUtils.unescapeJava(str);

In a key value pair, can a key be another k-v pair?

I know the following JSON objects are valid KV pairs:
{a:1,b:45,h:98}
{a:1,b:45,h:[a:1,b:45,h:98]}
-- Value of Key h is another array of KVP
{a:1,b:45,h:[98,97,65,43]}
But is this valid:
{a:1,b:45,{a:1,b:45,h:98}:98}
context is MongoDB's JSON objects
No. MongoDB uses JSON syntax and stores objects as JSON (well, technically BSON). json.org says very explicitly that the syntax for objects -- the things between {}, is string : value. In the same document, it goes on to say:
A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes
This would preclude you from using an object literal as a key.
I think that if you think about it enough you would realize that it doesn't make sense to use anything other than a string as a key anyway.

How to convert string to BSON using MongoDB C++ driver?

Similar to toString is there a way we can convert a string to BSON object? I need to remove a document using C++ driver the the remove function expects the query to have BSON object.
Use the fromjson method found here:
http://api.mongodb.org/cplusplus/1.5.4/namespacemongo.html#a4f542be0d0f9bad2d8cb32c3436026c2
BSONObj mongo::fromjson ( const string & str )
Create a BSONObj from a JSON <http://www.json.org> string.
In addition to the JSON extensions extensions described here
http://mongodb.onconfluence.com/display/DOCS/Mongo+Extended+JSON, this function accepts
certain unquoted field names and allows single quotes to optionally be used when
specifying field names and string values instead of double quotes. JSON unicode escape
sequences (of the form ) are converted to utf8.
Exceptions:
MsgAssertionException if parsing fails. The message included with this assertion includes
a rough indication of where parsing failed.

Is it possible to JSON a .NET dictionary when the key is a non-string object?

I would like to have controller GET action that returns a JSON-serialized dictionary. The key to the dictionary is a simple class with two primitives as properties - call it ClassOne. However, I receive the following error when attempting to JSON the dictionary:
System.Collections.Generic.Dictionary`2[[ClassOne],[ClassTwo]]' is not supported for serialization/deserialization of a dictionary, keys must be strings or objects.
The phrase "keys must be strings or objects" implies that it IS possible to serialize a dictionary that has objects as its keys. However, I cannot find a way to do so. What are my options in this situation?
Well, no. A dictionary from .net would serialize to a hash in Javascript. A hash can only have strings as keys, so you wouldn't be able to serialize a non-string key. You can simply transform your dictionary into a serializable one like this:
myDictionary.ToDictionary(k => k.Key.Prop1 + "|" + k.Key.Prop2, v => v.Value);
Perhaps cleaner would be to give ClassOne a ToString override and just call k.Key.ToString() in the code above.

Groovy map must be converted to JSON object with numerical object key

I am doing some processing with Groovy/Grails and the results are a map of type <String, Float>.
When returning the JSON object to the calling function (in this case, it's a flot diagram which requires [number,number] format), the key needs to be a number. This, in theory, is fine as my key to the map is a number in string form. I can't, however, figure out a way to create the JSON object with a numerical key.
I get results like this:
{"1":-9.814244910221474,"2":-9.710478606504552,"3":-9.636841089398253,"4":-9.524104819110796,"5":-9.522597036735684 ...}
instead of:
{1:-9.814244910221474,2:-9.710478606504552,3:-9.636841089398253,4:-9.524104819110796,5:-9.522597036735684 ...}
Does anyone know a way to force the JSON Map.encodeAsJSON() to produce an integer key? I've tried explicitly creating a map of type < integer,integer > before encoding it, and that doesn't work either.
Mike, Im looking at the json spec -- it appears that the keys must be strings. You should handle this client side.
http://www.json.org/