-1

I have a json like this:

{
   "Diagnoses": {
        "WESTERN EQUINE ENCEPHALITIS": {
            "ICD": "A83.1",
            "ID": "9"
        }
     },
   "ICD": {
        "A83.1": {
            "Name": "WESTERN EQUINE ENCEPHALITIS",
            "ID": "9"
        },
        "A83.2": {
            "Name": "EASTERN EQUINE ENCEPHALITIS",
            "ID": "10"
        }

     }
}

My actual json is much longer. There are about 8000 items within Diagnoses and ICD each. I'm trying to find the best way to load all the keys into a list. First, I have the entire json in a JObject. To put it into a list, I'm doing this:

IList<JToken> jsonDiagName = jDiagnosis["Diagnoses"].Children().ToList();

foreach (JToken diagnosis in jsonDiagName)
            {
                cb_DiagName.Items.Add(diagnosis.ToObject<JProperty>().Name);
            }

Where jDiagnosis is the JObject. However, with about 9000 items in the json, its taking about 3 minutes to load the list. So I searched for more efficient ways to do it and found this.

However, to try the suggestion in there, I need to extract the json under "Diagnoses" to be a JObject of its own. So, how can I make a JObject from an exising JObject?

Thank You

Sathya
  • 155
  • 1
  • 5
  • 18

2 Answers2

0

If you're dealing with a large object as you say, you probably do not want to read it all into memory at once, you should use a json reader.

If you want to just read the keys of the root object, you can do this:

IEnumerable<string> GetKeys(string path)
{
    using (var reader = new JsonTextReader(File.OpenText(path)))
    {
        while (reader.Read())
        {
            switch (reader.TokenType)
            {
            case JsonToken.PropertyName:
                if ((string)reader.Value == "Diagnoses") // only interested in "Diagnoses" property
                {
                    foreach (var key in _GetKeys(reader))
                        yield return key;
                    yield break;
                }
                reader.Skip();
                break;
            }
        }
    }

    IEnumerable<string> _GetKeys(JsonReader reader)
    {
        while (reader.Read())
        {
            switch (reader.TokenType)
            {
            case JsonToken.PropertyName:
                yield return (string)reader.Value;
                reader.Skip(); // skip the value of the property
                break;
            case JsonToken.EndObject:
                yield break;
            }
        }
    }
}
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
  • Hi, thanks for you answer. What you're suggesting is something that I'm trying to do . However, I don't want to read the keys of the root object, I want to read the keys of the child object. – Sathya Oct 26 '18 at 05:30
  • You would have to change the implementation to look for the desired object and output the keys. But the idea is the same. – Jeff Mercado Oct 26 '18 at 05:58
0

So, I managed to solve this myself instead.

I took what @New Contributer suggested of Deserialising the JSON but instead I serialised the JObject to string and then parsed that string back into a new JObject.

string diags = JsonConvert.SerializeObject(jDiagnosis["Diagnoses"]);
JObject jDiags = JObject.Parse(diags);

string[] names = jDiags.Properties().Select(p => p.Name).ToArray();
cb_DiagName.Items.AddRange(names);

Not sure why that thought process didn't occur to me earlier. :/

Sathya
  • 155
  • 1
  • 5
  • 18