我有一个如下所示的JSON字符串:
{
"MetaData": {
"ResourcesUsed": 1
},
"Result": [
{
"locations": [
{
"country": "Papua New Guinea",
"city": "Jacquinot Bay",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-08T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
},{
"country": "Papua New Guinea2",
"city": "Jacquinot Bay2",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-02T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
}
]
}
]
}
我使用Newtonsoft将其转换为JSON对象。我想要做的是按嵌套在每个locations
项目中的Result
字段对utcDate
数组中的locations
数组进行排序。我发现以下线程:C# Sort JSON string keys。但是,由于我的对象内部有数组,因此我仍然无法实现它,而该问题仅涉及按属性名称按字母顺序对对象内部的对象进行排序。
这是我到目前为止编写的一段代码:
public string GenerateJson()
{
var model = (JObject)JsonConvert.DeserializeObject(data);
Sort(model);
}
private void Sort(JObject jObj)
{
var props = jObj["Result"][0]["locations"].ToList();
foreach (var prop in props)
{
prop.Remove();
}
foreach (var prop in props.OrderBy(p => p.Name))
{
jObj.Add(prop);
if (prop.Value is JObject)
Sort((JObject)prop.Value);
if (prop.Value is JArray)
{
Int32 iCount = prop.Value.Count();
for (Int32 iIterator = 0; iIterator < iCount; iIterator++)
if (prop.Value[iIterator] is JObject)
Sort((JObject)prop.Value[iIterator]);
}
}
}
答案 0 :(得分:0)
您可以使用LINQ对每个单独的"Result[*].locations"
数组进行排序,如下所示:
// Load the JSON without parsing or converting any dates.
var model = JsonConvert.DeserializeObject<JObject>(data, new JsonSerializerSettings{ DateParseHandling = DateParseHandling.None });
// Construct a serializer that converts all DateTime values to UTC
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings{ DateTimeZoneHandling = DateTimeZoneHandling.Utc });
foreach (var locations in model.SelectTokens("Result[*].locations").OfType<JArray>())
{
// Then sort the locations by utcDate converting the value to UTC at this time.
var query = from location in locations
let utcDate = location.SelectToken("locTypeAttributes.utcDate").ToObject<DateTime>(serializer)
orderby utcDate
select location;
locations.ReplaceAll(query.ToList());
}
注意:
最初使用DateParseHandling.None
加载JSON,以防止将"localDate"
和"utcDate"
字符串过早地解释为具有统一{{3} }。
(有关Json.NET如何解释类似于日期的字符串的讨论,请参见 DateTime.Kind
。)
然后,我们使用Serializing Dates in JSON遍历所有DateTime
数组,其中"locations"
是SelectTokens("Result[*].locations")
通配符,选择[*]
数组中的所有条目
然后通过将嵌套的"Results"
反序列化为UTC日期,然后使用LINQ进行排序,对每个"locations"
数组进行排序。
最后使用JSONPath更新数组。
如果缺少任何locTypeAttributes.utcDate
属性,则将引发异常。如果可能,您可以反序列化为locTypeAttributes.utcDate
。
工作示例.Net小提琴JArray.ReplaceAll()
。