Search Unity

Deserializing Json Array that contains arrays, to object array.

Discussion in 'Scripting' started by cmatias, Jun 20, 2022.

  1. cmatias

    cmatias

    Joined:
    Feb 7, 2014
    Posts:
    7
    Hi there.
    I've been reading everything I found about raw JSON deserializing to objects, but I'm to newbee to face this JSON structure:

    I understand how to load my Items to an array of ClimatPoly[] type, but I don't know how to deserialize the contained Points array...

    Here is a sample of the JSON file :
    Code (CSharp):
    1. {
    2.     "Items": [
    3.         {
    4.             "Coordonnees": "iOS",
    5.             "id": "P1_CL_GC_3",
    6.             "Points": ["{0.8153064005433652, 0.22303484578714347}", "{0.8153647996297442, 0.22523130031371963}", "{0.8149728519153944, 0.22687271395095307}"]
    7.         },
    8.         {
    9.             "Coordonnees": "iOS",
    10.             "id": "P1_CL_GC_4",
    11.             "Points": ["{0.8217868273658131, 0.23282567723040115}", "{0.8233755819978078, 0.23300087448953702}"]
    12.         }
    13.     ]
    14. }
    Here is my object class structure :
    Basically, I want to fill "lesClimatsPoly" array with the items from the JSON file, but I also need to fill the variable length array "Points" inside the ClimatPoly class.

    Code (CSharp):
    1. public static class ClimatPolyArray
    2. {
    3.     public struct Point
    4.     {
    5.         public float x, y;
    6.         public Point(float px, float py)
    7.         {
    8.             x = px;
    9.             y = py;
    10.         }
    11.     }
    12.     public class ClimatPoly
    13.     {
    14.         public string Coordonnees;
    15.         public string id;
    16.         public Point[] Points;
    17.     }
    18.  
    19.     public static ClimatPoly[] lesClimatsPoly;
    20.  
    21.  
    22.     //public string Nom;
    23.  
    24.     public static void Load()
    25.     {
    26.         string theFile = "jsontestfile.json";
    27.         string filepath = Path.Combine(Environment.CurrentDirectory, @"Assets\Resources\", theFile);
    28.        
    29.         string jsonString = File.ReadAllText(filepath);
    30.         Debug.Log("jsonString : " + jsonString);
    31.         [...]
    32.     }
    33.  
    I've been looking at the chapter called "2. MULTIPLE DATA(ARRAY JSON)" on stackoverflow, but I dont know where to go from here...

    Any help would be greatly appreciated.
     
  2. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,999
    You can't directly load the numeric values inside the "Points" array since the elements in that array (from the json's perspective) are just strings. The content of those strings also does not represent valid json either. Curly brackets indicate an object in json and objects are always key-value pairs. However those strings more or less represent an array with 2 elements. Anyways, any json parser could only parse up to the string values. You would need to deconstruct those yourself.

    If you came up with that format yourself, I would strongly recommend to change it. It this is a third party API or something, I would give them a call and ask what brilliant mind came up with that silly format ^^.

    Further more using float would mean you're loosing a lot of precision. Floats only have about 7 decimal digits of precision. The values in the strings have 16 digits. So I would highly recommend to use a double.

    The usual structure that would represent your data would look something like this:

    Code (CSharp):
    1. [System.Serializable]
    2. public class JsonData
    3. {
    4.     public ClimatPoly[] Items;
    5. }
    6.  
    7. [System.Serializable]
    8. public class ClimatPoly
    9. {
    10.     public string Coordonnees;
    11.     public string id;
    12.     public string[] Points;
    13. }
    Here the "JsonData" class represents your whole json file and could be loaded with most json parsers (even with Unity's JsonUtility). Though as I said, each "point" is just a string and that string does not contain valid json and would need to be parsed / interpreted manually.
     
    cmatias likes this.
  3. cmatias

    cmatias

    Joined:
    Feb 7, 2014
    Posts:
    7
    Hi Bunny83.
    Thank you very much for your time and your help.

    I'm not used to programming in c#, and I was completely disappointed about two things :
    - First, arrays [] are not be dynamic !!! (I've never seen this in any other programming language....)
    I took me some time to understand that Arrays can be replaced by Lists easily.

    - [System.Serializable] is not only used to display properties in the unity inspector !
    There are so many tutorials on the internet that explains that the only purpose of "Serializable" is intended for displaying properties on the inspector panel that I had a hard time to understand that it is actually not so specific.

    You gave me a good starting point to understand what I was trying to do, so I first tried to create a Json file from the data structure you suggested (JsonData) , and it worked !
    After creating 2 new instances of ClimatPoly , my "JsonUtility.ToJson(myJsonData,true)" function return a text that looks like the Json file I wanted to read !
    Code (CSharp):
    1. {
    2.     "Items": [
    3.         {
    4.             "Coordonnees": "ios",
    5.             "id": "P1_CL_GC_3_id",
    6.             "Points": [
    7.                 "{0.8153064005433652, 0.22303484578714347}",
    8.                 "{0.8153647996297442, 0.22523130031371963}"
    9.             ]
    10.         },
    11.         {
    12.             "Coordonnees": "ios",
    13.             "id": "P1_CL_GC_4_id",
    14.             "Points": [
    15.                 "{0.8153064005433652, 0.22303484578714347}",
    16.                 "{0.8153647996297442, 0.22523130031371963}"
    17.             ]
    18.         }
    19.     ]
    20. }
    For the next step I converted my arrays to Lists :

    Code (CSharp):
    1. [System.Serializable]
    2.     public class JsonData
    3.     {
    4.         public List<ClimatPoly> Items;
    5.     }
    6.  
    7.     [System.Serializable]
    8.     public class ClimatPoly
    9.     {
    10.         public string Coordonnees;
    11.         public string Nom;
    12.         public string id;
    13.         public List<string> Points;
    14.     }
    Again, it worked as expected ! (great !)

    Finally, I reversed the operation to read my Json file with :
    Code (CSharp):
    1. JsonUtility.FromJson<JsonData>(jsonStringCorrected);
    Now the only thing left is to convert my points strings (like {0.8153064005433652, 0.22303484578714347}) to a Point struct with x and y.

    Thanks a lot Mr Bunny83 ! You rule !