Reputation: 1125
I am working in C#. I want to load a JSON string and delete an item by value. For example, in the following JSON, I want to remove the value of 2. So, in the resulting JSON string, the Dallas Store should have been removed.
[
{
"text":"Select Store",
"value":""
},
{
"text":"Austin Store",
"value":"1"
},
{
"text":"Dallas Store",
"value":"2"
},
{
"text":"Houston Store",
"value":"3"
},
{
"text":"Chicago Store",
"value":"4"
},
{
"text":"Los Angeles Store",
"value":"5"
}
]
I could parse the string with Newton Soft's JArray, loop through and add all the stores except the Dallas one in a new JArray. I am wondering is there a simpler Linq method to work on the JArray which will remove the expected item.
Upvotes: 3
Views: 4190
Reputation: 116721
You have a couple of options here since JArray
does not have a RemoveAll(Predicate<JToken> match)
method.
Firstly, you can use SelectTokens()
to find all JArray
items for which value == 2
and then remove them as follows:
var array = JArray.Parse(jsonString);
array.SelectTokens("[?(@.value == '2')]")
.ToList()
.ForEach(i => i.Remove());
The expression [?(@.value == '2')]
is a JSONPath query; for details and documentation see # JSONPath - XPath for JSON and Querying JSON with complex JSON Path.
Note that this may have quadratic performance in the number of items to be removed, and so might be unacceptably slow if you are removing a large number of items.
Secondly, you can grab JTokenExtensions.RemoveAll(this JArray array, Predicate<JToken> match)
from this answer to JArray - How to remove elements that are not contained in another list -fastest/best performance way:
public static partial class JTokenExtensions
{
/// <summary>
/// Removes all the elements that match the conditions defined by the specified predicate.
/// </summary>
public static void RemoveAll(this JArray array, Predicate<JToken> match)
{
if (array == null || match == null)
throw new ArgumentNullException();
array.ReplaceAll(array.Where(i => !match(i)).ToList());
}
}
Then remove your desired items as follows:
array.RemoveAll(i => (string)i["value"] == "2");
This will have linear performance in the number of items to be removed.
Demo fiddle here.
Upvotes: 2