0

With a JSON file that looks like this,

{ 
"dict": {"key": "value"} 
}

how can I make a dictionary named "dict" that looks like this one {"key": "value"} in Unity?

Here is my class.

[Serializable]
public class MyJson
{
    public Dictionary<string,string> dict;
}

I don't know why but when I try to use this class and the JsonUnility.FromJson() method it doesn't seem to change dict to that dictionary that I would expect. Instead it is just null.

EDIT: I've seen that in the Unity docs it says "dictionaries are not supported" so is there some convenient method to create the dictionary easily or will I have to piece it together myself with the data?

Here is a potential JSON. This kind of gets into another problem I was having though which is that I created the JSON with python meaning I could have different value types in my dictionary, but that won't work for C# so for now it's all just strings and I'll figure something out for that later. (Probably by making it all lists then the ones that are only strings will just have 1 element)

{
    "pages": [
    {
        "files": "[null, null, null, null]", 
        "imagepath": "C:/Users/Jeff/Pictures/location_sharing.png", 
        "pageNum": "0", 
        "polygons": "[[[122, 184], [178, 180], [174, 159], [126, 158]], [[191, 157], [194, 185], [241, 183], [246, 154]], [[334, 219], [323, 236], [323, 247], [338, 259], [358, 259], [364, 236], [356, 221], [344, 215]], [[512, 221], [503, 235], [508, 256], [518, 267], [538, 260], [548, 250], [541, 228], [529, 218]]]"
    }, 
    {
        "files": "[null, null, null]", 
        "imagepath": "C:/Users/Jeff/Pictures/node.png", 
        "pageNum": "1", 
        "polygons": "[[[189, 149], [181, 152], [188, 170], [197, 182], [196, 173], [192, 153]], [[233, 176], [258, 171], [244, 144]], [[116, 260], [143, 227], [181, 210], [225, 202], [276, 199], [305, 210], [353, 222], [360, 252], [361, 266]]]"
    }]}
ToxicGLaDOS
  • 441
  • 5
  • 16
  • read - http://stackoverflow.com/a/38535392/294884 – Fattie Aug 16 '16 at 18:50
  • Possible duplicate of [What's the best way to loop through a JSON of sales data to create a graph in Unity?](http://stackoverflow.com/questions/38535239/whats-the-best-way-to-loop-through-a-json-of-sales-data-to-create-a-graph-in-un) – Fattie Aug 16 '16 at 18:50
  • 1
    Possible duplicate of [Deserialization of JSON using MiniJSON in Unity C#](http://stackoverflow.com/questions/36239705/deserialization-of-json-using-minijson-in-unity-c-sharp) – Cabrra Aug 16 '16 at 18:56
  • 1
    @JoeBlow - According to https://docs.unity3d.com/Manual/JSONSerialization.html, *types like `Dictionary<>` are not supported*. Can the built-in `JsonUtility` actually handle a `Dictionary`? The question implies that it cannot. – dbc Aug 16 '16 at 19:08
  • I suppose that is what my question is really about and I should address that. So the real question becomes is there a workaround for that because I do really need a dictionary based on the data in the JSON file. – ToxicGLaDOS Aug 16 '16 at 19:12
  • 1
    Can you tweak your example so it passes a json validator like the one on http://jsonlint.com/, you likey just need to throw a `]}` on the end, but I just want to make sure and not make assumptions. Also, your data structure does not look like a `public Dictionary dict;`, it looks like a `public Page[] pages;` – Scott Chamberlain Aug 16 '16 at 19:44

2 Answers2

5

Your updated example schema does not look like it is a dictionary at all. Because each element in pages is not actual nested json but a string that looks like it could be interpeted as nested json all you need to do is have

[Serializable]
public class PageContainer
{
    Page[] pages;
}

[Serializable]
public class Page
{
    public string files;
    public string imagepath;
    public string pagenum;
    public string polygons;
}

Then do a

PageContainer pageContainer = JsonUtility.FromJson<PageContainer>(yourString);

You would then potentially need to do further

FileContainer fileContainer = JsonUtility.FromJson<FileContainer>(pageContainer.files);
PolygonContainer polygonContainer = JsonUtility.FromJson<PolygonContainer>(pageContainer.polygons);

and make the necessary classes as needed.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • That clears things up a lot. I read a post somewhere else that had a really similar idea but I didn't understand it. That makes perfect sense now. I never thought of making another json instead of using the stuff in the "{}" as a dictionary. I think I missed this because I created the data as a dictionary in python then when it used the same notation (curly braces) I just thought it must be a dictionary and that's the only option. I think this will work out great! Thanks a bunch either way! – ToxicGLaDOS Aug 16 '16 at 19:59
  • @ToxicGLaDOS oops, i forgot to put on `[Serializable]` on the two classes, you will need that for JsonUtility to work. – Scott Chamberlain Aug 16 '16 at 20:14
  • actually, this answer not answers the question of this post. What if I have dictionary with unknown keys ? I can't create Serializable class for this case. – Aleksandrs May 05 '21 at 09:06
0

I would create a model of what ever your storing. I'll call it KeyValue because I am unsure of what you are actually storing. Then I would give that model two string properties as you specified. One string property called key, and another string property called value.

Dictionary<KeyValue> keyValues = new Dictionary<KeyValue>();
    //of course here instead of hard coding I would pass values in from where ever you are getting them.
    KeyValue kv1 = new KeyValue("myKey1", "myValue1");
    KeyValue kv2 = new KeyValue("myKey2", "myValue2");

    keyValues.Add(kv1);
    keyValues.Add(kv2);

So this should give you a good jumping point assuming I understand you question correctly, but the general idea is to create a dictionary of the type you need then populate that dictionary.

alphamalle
  • 192
  • 1
  • 3
  • 15