从JObject中删除重复项

时间:2016-12-20 14:51:27

标签: c# json.net

我有一个像这样的JSON字符串:

{
    "managedObjects": [
         {
            "id": "13289",      
            "name": "xxx"      
         },
         {
            "id": "13290",      
            "name": "yyy" 
         },
         {
            "id": "13289",      
            "name": "xxx" 
         }]
}

我正在解析为JObject

JObject obj = JObject.Parse(json)

现在,如何从此数组中删除重复元素?我想从JObject(这里是id=13289)中删除id中的重复元素。

4 个答案:

答案 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;

虽然有点乱。