我有一个像这样的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?
谢谢
答案 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);
不确定为什么我较早就没有这种想法。 :/