Kunal Mukherjee
Kunal Mukherjee

Reputation: 5853

Filtering out the set difference of two List<JObject> in C# using LINQ

I have 2 List<JObject> to be compared for their set differences,

The format of the two List<JObject> to be compared are as follows:

This is the JSON structure for my base List<JObject> :

[
    {
        "name": "competency",
        "subLists": [
            {
                "canonicalForm": "c1",
                "list": [
                    "c one",
                    "c 1",
                    "cone",
                    "Cone"
                ]
            }
        ],
        "roles": []
    },
    {
        "name": "demoList",
        "subLists": [],
        "roles": []
    }
]

This is the JSON structure of the List<JObject> that I want to find the set difference against:

[
    {
        "name": "competency",
        "subLists": [
            {
                "canonicalForm": "c1",
                "list": [
                    "c one",
                    "c 1",
                    "cone",
                    "Cone",
                    "C ONE"
                ]
            },
            {
                "canonicalForm": "c2",
                "list": [
                    "c two",
                    "c 2"
                ]
            }
        ],
        "roles": []
    },
    {
        "name": "leavetype",
        "subLists": [
            {
                "canonicalForm": "annual",
                "list": [
                    "Easter"
                ]
            }
        ],
        "roles": []
    },
    {
        "name": "demoList",
        "subLists": [],
        "roles": []
    }
]

With the output set difference JSON being:

[
    {
        "name": "competency",
        "subLists": [
            {
                "canonicalForm": "c1",
                "list": [
                    "c one",
                    "c 1",
                    "cone",
                    "Cone",
                    "C ONE"
                ]
            },
            {
                "canonicalForm": "c2",
                "list": [
                    "c two",
                    "c 2"
                ]
            }
        ],
        "roles": []
    },
    {
        "name": "leavetype",
        "subLists": [
            {
                "canonicalForm": "annual",
                "list": [
                    "Easter"
                ]
            }
        ],
        "roles": []
    }
]

I have tried using the following code using two for-loops:

List<JObject> baseList = JsonConvert.DeserializeObject<List<JObject>>(baseListString);
List<JObject> comparedList = JsonConvert.DeserializeObject<List<JObject>>(comparedListString);

List<JObject> finalResultList = new List<JObject>();


for (int i = 0; i < baseList.Count; i++)
{
     for (int j = 0; i < comparedList.Count; j++)
     {
        if(baseList[i]["subLists"] != comparedList[j]["subLists"])
                        finalResultList.Add(comparedList[j]);
     }
}

But this is not cutting it, I want to compare the entire JObject based on the key values of name, canonicalForm, list keys and filter out the set difference using LINQ. But I am unable to do so.

I have tried using .Except() extension method but that is not working as well.


Edit:

I want to check if there is any change in the 3 keys which are: name, canonicalForm and list, if there are any change in the compareObject compared to the BaseObject I want to return the JObject which has the change. The output is displayed above.


Any help will be appreciated.

Upvotes: 1

Views: 171

Answers (1)

Kunal Mukherjee
Kunal Mukherjee

Reputation: 5853

I finally solved my problem by implementing the IEqualityComparer for JObject.


Here is my JObjectEqualityComparer class:

public class JObjectEqualityComparer : IEqualityComparer<JObject>
    {
        public bool Equals(JObject x, JObject y)
        {
            if (x == null && y == null)
                return true;
            if ((x != null && y == null) || (x == null && y != null))
                return false;

            return JObject.DeepEquals(x, y);
        }

        public int GetHashCode(JObject obj)
        {
            JTokenEqualityComparer comparer = new JTokenEqualityComparer();
            int hashCode = comparer.GetHashCode(obj);
            return hashCode;
        }
    }

Finally I have used this overload of .Except() extension method to find the Set Difference.

enter image description here


Here is the code:

List<JObject> baseList = JsonConvert.DeserializeObject<List<JObject>>(baseListString);
List<JObject> comparedList = JsonConvert.DeserializeObject<List<JObject>>(comparedListString);

List<JObject> finalResultList = new List<JObject>();

finalResultList = comparedList.Except(baseList, new JObjectEqualityComparer()).ToList();

Thanks to Ed Plunkett, dbc and Coding Yoshi for pointing me out in the correct direction.

Upvotes: 1

Related Questions