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

and*_*dyJ 5 c# json json.net

我有一个想要在C#中修改的JSON字符串。我希望能够在其中一个子值是某个值时删除一组数据。

采取以下

 {
  "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
    }]
 }}
Run Code Online (Sandbox Code Playgroud)

上面显示了两个响应结果。我希望能够在匹配其子“ 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
    }]
  }}
Run Code Online (Sandbox Code Playgroud)

我将需要对Json文件执行多个删除操作。Json文件可能包含成千上万个结果,我确实需要尽可能高效的方法。

任何帮助,不胜感激。

L.B*_*L.B 5

var jObj = (JObject)JsonConvert.DeserializeObject(json);
HashSet<string> idsToDelete = new HashSet<string>() { "2f7661ae3c7a42dd9f2eb1946262cd24" };

jObj["response"]["docs"]
    .Where(x => idsToDelete.Contains((string)x["id"]))
    .ToList()
    .ForEach(doc=>doc.Remove());

var newJson = jObj.ToString();
Run Code Online (Sandbox Code Playgroud)


tme*_*ser 5

在过去的 10 分钟左右,我一直试图将其压缩为更好的 LINQ 语句,但已知 Id 列表本质上改变了每个元素的评估方式这一事实意味着我可能不会得到它发生。

        var jObj = (JObject)JsonConvert.DeserializeObject(json);
        var docsToRemove = new List<JToken>();
        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();
Run Code Online (Sandbox Code Playgroud)

这似乎适用于我用来测试的蹩脚小控制台应用程序,但我的测试仅限于上面的示例数据,因此如果有任何问题,请继续发表评论,以便我可以修复它们。

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