根据C#中的条件从JSON中删除元素

我有一个JSON字符串,我希望能够在C#中修改。 我希望能够基于其中一个子值是特定值来删除一组数据。

请采取以下措施

{ "responseHeader":{ "status":0, "QTime":0, "params":{ "explainOther":"", "fl":"*,score", "indent":"on", "start":"0", "q":"*:*", "hl.fl":"", "qt":"", "wt":"json", "fq":"", "version":"2.2", "rows":"2"} }, "response":{"numFound":2,"start":0,"maxScore":1.0,"docs": [{ "id":"438500feb7714fbd9504a028883d2860", "name":"John", "dateTimeCreated":"2012-02-07T15:00:42Z", "dateTimeUploaded":"2012-08-09T15:30:57Z", "score":1.0 }, { "id":"2f7661ae3c7a42dd9f2eb1946262cd24", "name":"David", "dateTimeCreated":"2012-02-07T15:02:37Z", "dateTimeUploaded":"2012-08-09T15:45:06Z", "score":1.0 }] }} 

上面显示了两个响应结果。 我希望能够在其子“id”值匹配时删除整个父响应结果组,例如,如果我的id是“2f7661ae3c7a42dd9f2eb1946262cd24”,我希望删除第二组,因此我的结果将如下所示。

 { "responseHeader":{ "status":0, "QTime":0, "params":{ "explainOther":"", "fl":"*,score", "indent":"on", "start":"0", "q":"*:*", "hl.fl":"", "qt":"", "wt":"json", "fq":"", "version":"2.2", "rows":"2"}}, "response":{"numFound":2,"start":0,"maxScore":1.0,"docs":[ { "id":"438500feb7714fbd9504a028883d2860", "name":"John", "dateTimeCreated":"2012-02-07T15:00:42Z", "dateTimeUploaded":"2012-08-09T15:30:57Z", "score":1.0 }] }} 

我需要在Json文件上执行多个删除操作。 Json文件可能包含数千个结果,我真的需要尽可能最高效的方式。

任何帮助非常感谢。

在过去的10分钟左右,我一直试图将其压缩成更好的LINQ语句,但是已知的ID列表固有地改变了每个元素的评估方式,这意味着我可能不会那样做发生。

  var jObj = (JObject)JsonConvert.DeserializeObject(json); var docsToRemove = new List(); foreach (var doc in jObj["response"]["docs"]) { var id = (string)doc["id"]; if (knownIds.Contains(id)) { docsToRemove.Add(doc); } else { knownIds.Add(id); } } foreach (var doc in docsToRemove) doc.Remove(); 

这似乎适合我旋转测试的糟糕的小控制台应用程序,但我的测试仅限于上面的示例数据,所以如果有任何问题继续并留下评论,所以我可以修复它们。

对于它的价值,这将基本上以线性时间运行,相对于您提供的元素数量,这可能会让您获得更多的算法性能,而不会对此问题感到惊讶。 使用任务并行库调用将处理其自己的小页面并返回已清理的JSON字符串的工作人员,将约100个记录的每个页面旋转到其自己的任务中。 如果你在多核机器上运行它肯定会使这个更快,我很乐意提供一些代码来帮助你开始,但它也是一个巨大的过度工程,因为它提出了问题的范围。

 var jObj = (JObject)JsonConvert.DeserializeObject(json); HashSet idsToDelete = new HashSet() { "2f7661ae3c7a42dd9f2eb1946262cd24" }; jObj["response"]["docs"] .Where(x => idsToDelete.Contains((string)x["id"])) .ToList() .ForEach(doc=>doc.Remove()); var newJson = jObj.ToString(); 

上面的答案都没有对我.Parent.Remove() ,我不得不从Parent.Parent.Remove() )中Remove()子,而不仅仅是Remove()它。 下面的工作代码示例:

 namespace Engine.Api.Formatters { using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Formatting; using System.Net.Http.Headers; using System.Threading.Tasks; using System.Web.Script.Serialization; using System.Xml; using System.Xml.Serialization; public class ReducedJson { public dynamic WriteToStreamAsync(object value) { var json = new JavaScriptSerializer().Serialize(value); var serializedJson = (JObject)JsonConvert.DeserializeObject(json); foreach (var response in serializedJson["ProductData"]["Motor"]["QuoteResponses"]) { response["NetCommResults"].Parent.Remove(); foreach (var netCommResult in response["BestPriceQuote"]["NetCommResults"]) { netCommResult["Scores"].Parent.Remove(); } } return serializedJson; } } 

希望这能为您节省一些时间。

我只是找到另一个答案。

 var aJson = JsonConvert.DeserializeObject(json); var doc = aJson["response"]["docs"]; JObject docs = new JObject(); docs["docs"] = doc; // remove docs.SelectTokens(string.Format("docs[?(@.id == '{0}')]", "2f7661ae3c7a42dd9f2eb1946262cd24")).ToList().ForEach(i => i.Remove()); // replace aJson.SelectToken("response.docs").Replace(docs["docs"]);