我有一个像这样的JSON字符串:
{
"managedObjects": [
{
"id": "13289",
"name": "xxx"
},
{
"id": "13290",
"name": "yyy"
},
{
"id": "13289",
"name": "xxx"
}]
}
我正在解析为JObject
JObject obj = JObject.Parse(json)
现在,如何从此数组中删除重复元素?我想从JObject(这里是id=13289
)中删除id中的重复元素。
答案 0 :(得分:2)
你不需要为此使用课程。
// Get your JObject as you've already shown
var obj = JObject.Parse(json);
// Use LINQ to create a List<JToken> of unique values based on ID
// In this case the first occurence of the ID will be kept, repeats are removed
var unique = obj["managedObjects"].GroupBy(x => x["id"]).Select(x => x.First()).ToList();
// Iterate backwards over the JObject to remove any duplicate keys
for (int i = obj["managedObjects"].Count() - 1; i >= 0; i--)
{
var token = obj["managedObjects"][i];
if (!unique.Contains(token))
{
token.Remove();
}
}
// Re-serialize into JSON
var result = JsonConvert.SerializeObject(obj);
输出:
{
&#34; managedObjects&#34;:[
{
&#34; ID&#34;:&#34; 13289&#34 ;,
&#34;名称&#34;:&#34; XXX&#34;
},
{
&#34; ID&#34;:&#34; 13290&#34 ;,
&#34;名称&#34;:&#34; YYY&#34;
}
]
}
其他属性以及&#34; name&#34;应该像任何其他节点一样保存。
答案 1 :(得分:0)
我不知道是否有办法直接用Json.Net指定它,但解决方案是(如果您的数组顺序无关紧要)请在自定义类结构中读取带有重载的json Equals
方法:
var obj = JsonConvert.DeserializeObject<Container>(json);
// ...
public class Container
{
public HashSet<ManagedObject> ManagedObjects { get; set;}
}
public class ManagedObject
{
public string Id { get; set; }
public string Name { get; set; }
protected bool Equals(ManagedObject other)
{
return string.Equals(Id, other.Id);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((ManagedObject)obj);
}
public override int GetHashCode()
{
return (Id != null ? Id.GetHashCode() : 0);
}
}
答案 2 :(得分:0)
您可以在本地创建ManagedObject类型,然后将json反序列化为此类型。然后,您可以使用linq获取不同的列表。这是一个控制台应用程序,展示了这一点;
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace ConsoleApplication28
{
class Program
{
static void Main(string[] args)
{
var json =
"{\r\n\"managedObjects\": [\r\n{\r\n \"id\": \"13289\", \r\n \"name\": \"xxx\" \r\n},\r\n{\r\n \"id\": \"13290\", \r\n \"name\": \"yyy\" \r\n},\r\n{\r\n \"id\": \"13289\", \r\n \"name\": \"xxx\" \r\n}]\r\n}";
var managedObjectCollection = JsonConvert.DeserializeObject<ManagedObjectCollection>(json);
var distinctManagedObjects = managedObjectCollection.managedObjects.GroupBy(a => a.id).Select(b => b.First());
foreach (var distinctManagedObject in distinctManagedObjects)
{
Console.WriteLine("Id: {0}, Name: {1}", distinctManagedObject.id, distinctManagedObject.name);
}
Console.ReadLine();
}
class ManagedObjectCollection
{
public IEnumerable<ManagedObject> managedObjects { get; set; }
}
class ManagedObject
{
public int id { get; set; }
public string name { get; set; }
}
}
}
我感谢你提供了一个简化的例子,但是对于一个更复杂的例子,你只需要创建/扩展你要反序列化的类。
答案 3 :(得分:0)
您需要以下课程:
public class ManagedObject
{
public string Id { get; set; }
public string Name { get; set; }
}
public class RootObject
{
public List<ManagedObject> ManagedObjects { get; set; }
}
class MyComparer : IEqualityComparer<ManagedObject>
{
public bool Equals(ManagedObject x, ManagedObject y)
{
return x.Id.Equals(y.Id);
}
public int GetHashCode(ManagedObject obj)
{
return obj.Id.GetHashCode();
}
}
然后你可以反序列化你的json,如下所示:
var test = JsonConvert.DeserializeObject<RootObject>(json);
并从ManagedObjects列表中删除重复项:
var newManagedObject = test.ManagedObjects.Distinct(new MyComparer()).ToList();
test.ManagedObjects = newManagedObject;
虽然有点乱。