I have a JObject with a JSON like it:
{"name" : "user1", "groups" : ["group 1", "group2"]}
I would like to delete one group by the name. So I have a code like this:
JObject userJson = JObject.Parse(user);
JArray groups = userJson["groups"] as JArray;
JToken group = new JValue (groupName);
groups.Remove(group);
However the method JArray.remove(Jtoken item) return false (that means that it couldn't be deleted). Here the information:
https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JArray_Remove.htm
So tried to set the parameter like JToken group = new JValue (groupName);
JToken group = new JValue (groupName); as JToken
and JValue group = new JValue (groupName);
But it doesnt work :S
This guy explains JToken hierarchy very good but I don't know what I'm not doing right.
The basic issue is that the
JToken
hierarchy is doubly-connected graph. That is, each token knows itsParent
and each parent knows itsChildren
. Indeed, if you add a token that already has a parent to a parent, it gets cloned, as explained here.Thus, since every token knows its parent, when you try to remove a token from a parent, Json.NET might do one of two things:
And, in fact, Json.NET chooses the former option.
Jarray.Remove(JToken item)
callsJContainer.RemoveItem()
which callsJArray.IndexOfItem()
to determine the index of the item to remove. This method, in turn, uses reference equality:Since your
JToken group = new JValue (groupName)
does not belong to theJArray groups
, it is not removed.So, what are your options to remove a JSON array item by value? You could:
Search using LINQ:
Search using
JTokenEqualityComparer
, which can be used to search for complex objects as well as primitive values:Search using
SelectTokens()
:SelectTokens()
supports the JSONPath query syntax which enables searching though arrays for matching items.Finally, a note about the documentation for
RemoveItem()
. It states (italics added):Since we have seen that a token that has a parent is cloned when added to a parent, it seems there can only ever be one occurrence of any token within a given parent. Yet the documentation seems to imply otherwise; I would hazard a guess that this particular documentation sentence is obsolete and dates from some much earlier version of Json.NET where the same token could appear within a parent multiple times.