问题描述
我有一个想要在C#中修改的JSON字符串.我希望能够在其中一个子值是某个值时删除一组数据.
I have a JSON string that I want to be able to amend in C#. I want to be able to delete a set of data based when one of the child values is a certain value.
采取以下行动
{
"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",则希望删除第二个响应组,因此结果如下
There are two response results shown above. I want to be able to remove the whole parent response result group when its child "id" value is matched, for example if my id was "2f7661ae3c7a42dd9f2eb1946262cd24", I would want the second group to be deleted and thus my result would look as follows.
{
"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文件可能包含成千上万个结果,我确实需要尽可能高性能的方法.
I will need to perform multiple delete operations on the Json file. The Json file could contain thousands of results and I really need the most performant way possible.
任何帮助都将不胜感激.
Any help greatly appreciated.
推荐答案
最近十分钟左右,我一直试图将其压缩为更好的LINQ语句,但是已知ID的列表在本质上正在发生变化如何评估每个元素意味着我可能不会实现这一目标.
I've been attempting to compress this into a nicer LINQ statement for the last 10 minutes or so, but the fact that the list of known Ids is inherently changing how each element is evaluated means that I'm probably not going to get that to happen.
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();
这似乎与我测试的笨拙的小型控制台应用程序配合使用,但是我的测试仅限于上面的示例数据,因此,如果有任何问题,请留下评论,以便我进行修复.
This seems to work well with the crappy little console app I spun up to test, but my testing was limited to the sample data above so if there's any problems go ahead and leave a comment so I can fix them.
就其价值而言,这基本上相对于您喂入它的元素数量以线性时间运行,这很可能会使您获得更多的算法性能,而不会对此问题感到欢欣鼓舞.使用Task Parallel Library调用一个将处理自己的小页面并返回清洗后的JSON字符串的工作程序,可以将约100条记录的每个页面分解为自己的任务.如果您在多核计算机上运行它,那肯定会加快速度,并且我很乐意提供一些代码来帮助您入门,但是对于出现的问题,这也是一个巨大的过度设计.
For what it's worth, this will basically run in linear time with respect to how many elements you feed it, which is likely all the more algorithmic performance you're going to get without getting hilarious with this problem. Spinning each page of ~100 records off into its own task using the Task Parallel Library invoking a worker that will handle its own little page and returned the cleaned JSON string comes to mind. That would certainly make this faster if you ran it on a multi-cored machine, and I'd be happy to provide some code to get you started on that, but it's also a huge overengineering for the scope of the problem as it's presented.
这篇关于根据C#中的条件从JSON中删除元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!