JArray.Remove(JToken) does not delete
我有一个带有JSON的JObject,如下所示:
1 | {"name" :"user1","groups" : ["group 1","group2"]} |
我想按名称删除一个组。所以我有这样的代码:
1 2 3 4 5 6 | JObject userJson = JObject.Parse(user); JArray groups = userJson["groups"] as JArray; JToken group = new JValue (groupName); groups.Remove(group); |
但是方法JArray.remove(Jtoken item)返回false(这意味着它不能被删除)。这里的信息:
https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JArray_Remove.htm
因此尝试设置像
这个人很好地解释了JToken层次结构,但是我不知道我做错了什么。
https://stackoverflow.com/a/38560188/8849646
基本问题是
因此,由于每个令牌都知道其父级,因此当您尝试从父级中删除令牌时,Json.NET可能会执行以下两项操作之一:
事实上,Json.NET选择了前一个选项。
1 2 3 4 | internal override int IndexOfItem(JToken item) { return _values.IndexOfReference(item); } |
由于您的
那么,按值删除JSON数组项的选项是什么?您可以:
-
使用LINQ搜索:
1groups.Where(i => i.Type == JTokenType.String && (string)i == groupName).ToList().ForEach(i => i.Remove()); -
使用
JTokenEqualityComparer 进行搜索,该搜索可用于搜索复杂对象以及原始值:1
2var comparer = new JTokenEqualityComparer();
groups.Where(i => comparer.Equals(i, group)).ToList().ForEach(i => i.Remove()); -
使用
SelectTokens() 搜索:1userJson.SelectTokens(string.Format("groups[?(@ == '{0}')]", groupName)).ToList().ForEach(i => i.Remove());SelectTokens() 支持JSONPath查询语法,该语法使您可以在数组中搜索匹配项。
最后,关于
JArray.Remove Method (JToken) Removes the first occurrence of a specific object from the JArray.
由于我们已经看到具有父级的令牌在添加到父级时会被克隆,因此在给定的父级中似乎永远都不会出现任何令牌。然而,文档似乎暗示着其他情况。我可能会猜测,这个特定的文档句子已经过时,并且可以追溯到Json.NET的早期版本,在该版本中,相同的令牌可能在父级中多次出现。
1 2 3 4 5 6 7 | //Removing obj from oldArray private static JArray RemoveValue(JArray oldArray, dynamic obj) { List<string> temp2 = oldArray.ToObject<List<string>>(); temp2.Remove(obj); return JArray.FromObject(temp2); } |