如何用JObject制作JObject?

时间:2018-10-26 03:39:18

标签: c# winforms json.net

我有一个像这样的json:

{
   "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"
        }

     }
}

我的实际json更长。诊断和ICD中每个都有大约8000个项目。我正在尝试找到将所有键加载到列表中的最佳方法。首先,我在JObject中拥有整个json。要将其放入列表,我正在这样做:

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

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

jDiagnosis是JObject。但是,由于json中有大约9000个项目,因此加载列表大约需要3分钟。因此,我搜索了更有效的方法来找到它,并发现了this

但是,要尝试其中的建议,我需要将“ Diagnoses”下的json提取为自己的JObject。那么,如何从现有的JObject制作JObject?

谢谢

2 个答案:

答案 0 :(得分:0)

如果您要处理一个大对象,您可能不想立即将其全部读入内存,则应使用json阅读器。

如果只想读取根对象的键,则可以执行以下操作:

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;
            }
        }
    }
}

答案 1 :(得分:0)

因此,我设法自己解决了这个问题。

我接受了@New Contributer提出的反序列化JSON的建议,但我将JObject序列化为字符串,然后将该字符串解析回新的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);

不确定为什么我较早就没有这种想法。 :/