【问题标题】:Filtering out the set difference of two List<JObject> in C# using LINQ使用 LINQ 在 C# 中过滤掉两个 List<JObject> 的集合差异
【发布时间】:2018-05-14 14:27:09
【问题描述】:

我有 2 个 List&lt;JObject&gt; 要比较它们的设置差异,

要比较的两个List&lt;JObject&gt;的格式如下:

这是我的基础 List&lt;JObject&gt; 的 JSON 结构:

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

这是 List&lt;JObject&gt; 的 JSON 结构,我想找到它的集合差异:

[
    {
        "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": []
    }
]

与输出集差异 JSON 为:

[
    {
        "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": []
    }
]

我已尝试使用以下代码,使用两个 for 循环:

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]);
     }
}

但这不是削减它,我想根据namecanonicalFormlist键的键值比较整个JObject,并使用LINQ过滤掉设置的差异。但我做不到。

我曾尝试使用.Except() 扩展方法,但效果不佳。


编辑:

我想检查 3 个键是否有任何变化:namecanonicalFormlist,如果 compareObject 与 BaseObject 相比有任何变化,我想返回 JObject有变化。输出显示在上面。


任何帮助将不胜感激。

【问题讨论】:

  • Except 不起作用,baseList[i]["subLists"] != comparedList[j]["subLists"] 也不起作用。它们不会起作用,因为简单地将一个列表与另一个列表进行比较 (!=) 并不是您所追求的。您需要说明在您的情况下平等和差异意味着什么的规则。然后为这些规则编写代码。我们不知道规则,因为您没有告诉我们。
  • 使用this 答案创建实际的类并覆盖它们的Equals 方法。这将是您为每个类编写的少量代码以及它们如何比较,因此它会更容易。为每个需要比较的类编写代码。然后你可以在你的循环中使用Equals,看看它们是否相等。这需要时间,所以只需放松一下,一步一步走。花更多时间思考,减少编程。
  • @KunalMukherjee 通常,在编程领域,如果可能,我们会通过使用现有代码(在这种情况下显然不是)或编写自己的代码来完成那种(或任何)性质的任务代码。
  • 您可以编写自己的方法来比较序列(其中只有一个循环,而不是四个循环)。那将是非常好的做法,我推荐它。您也可以使用 Enumerable.SequenceEqual(),它的行为与嵌套属性的文档完全一致。

标签: c# arrays json linq json.net


【解决方案1】:

我终于通过为JObject 实现IEqualityComparer 解决了我的问题。


这是我的JObjectEqualityComparer 课程:

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;
        }
    }

最后我使用了.Except()扩展方法的重载来找到Set Difference。


代码如下:

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();

感谢Ed PlunkettdbcCoding Yoshi 为我指明了正确的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-26
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多