使用linq在多个列表中查找重复项

时间:2014-11-07 00:44:56

标签: c# linq

我有4个类,每个类都继承自同一个基类。他们都有Id&路径属性的共同点。当我的数据从xml加载时,我根据这些类构建了4个列表。

我已经获得以下代码,可以比较2个列表:

var list1 = settings.EmailFolders.Select(m => m.Path).ToList().
Intersect(settings.LogPaths.Select(m=>m.Path).ToList()).ToList();

但我喜欢

  1. 我想将第一个列表与其他3个列表进行比较,并找出是否存在重复路径。

  2. 如果没有找到,我想要应用相同的逻辑比较第二个列表并将其与其他列表进行比较。

  3. 如果没有找到,我想要应用相同的逻辑比较第三个列表并将其与最后一个列表进行比较。

  4. 请注意,我不希望在一个过程中找到第1,2和3点,因为如果找到重复项,我想报告相关错误。

    如果我重复使用上述内容并添加额外的Intersect附加列表,

    var list1 = settings.EmailFolders.Select(m => m.Path).ToList().
    Intersect(settings.LogPaths.Select(m=>m.Path).ToList()).
    Intersect(settings.SuccessPaths.Select(m=>m.Path).ToList()).
    Intersect(settings.FailurePaths.Select(m=>m.Path).ToList()).List();
    

    上面想要在每个操作符之间应用and运算符而不是or运算符,这不是我想要的。我需要知道我的EmailFolder.Path中是否已经使用了FailurePaths或LogPaths或SuccessPaths中使用的任何Path

    更新:

    我已根据@Devuxer建议更新了我的问题,这是正确的答案,但我没有使用字符串数组,而是基于所有包含{{1属性。

    Path

    请注意,在上面的示例中,为了简单起见,我刚刚为每个加载相关数据的函数声明了我的列表,但在我的情况下,所有数据都被反序列化并立即加载。

2 个答案:

答案 0 :(得分:0)

您可以使用属性进行比较

来使用包含
 var result = list1.Where(x => list2.Contains(x.Path));

它将提供list1中同样位于list2

中的所有项目

如果您只想要计数,那么最后使用.Count()

同样的规则适用于比较其他3个列表

答案 1 :(得分:0)

我可能会稍微误解你的要求,但看起来你想要这样的东西:

var emailFolders = new[] { "a", "b", "c" };
var logPaths = new[] { "c", "d", "e" };
var successPaths = new[] { "f", "g", "h" };
var failurePaths = new[] { "a", "c", "h" };

var pathCollisions = emailFolders
    .Intersect(logPaths)
    .Select(x => new { Type = "Email-Log", Path = x })
    .Concat(emailFolders
        .Intersect(successPaths)
        .Select(x => new { Type = "Email-Success", Path = x }))
    .Concat(emailFolders
        .Intersect(failurePaths)
        .Select(x => new { Type = "Email-Failure", Path = x }));

这导致:

Type          | Path
--------------------
Email-Log     |  c 
Email-Failure |  a 
Email-Failure |  c
--------------------

如果这是您要找的,Intersect绝对是找到重复项的正确方法。我刚刚添加了一些Concat子句并提供了Type,因此您可以看到发生了什么类型的路径冲突。

修改

你问题中的子弹似乎要求提出与你问题的最后一句不同的内容。

如果你真的想要进行所有比较,一种方法是添加更多Concat条款:

var pathCollisions = emailFolders
    .Intersect(logPaths)
    .Select(x => new { Type = "Email-Log", Path = x })
    .Concat(emailFolders
        .Intersect(successPaths)
        .Select(x => new { Type = "Email-Success", Path = x }))
    .Concat(emailFolders
        .Intersect(failurePaths)
        .Select(x => new { Type = "Email-Failure", Path = x }))
    .Concat(logPaths
        .Intersect(successPaths)
        .Select(x => new { Type = "Log-Success", Path = x }))
    .Concat(logPaths
        .Intersect(failurePaths)
        .Select(x => new { Type = "Log-Failure", Path = x }))
    .Concat(successPaths
        .Intersect(failurePaths)
        .Select(x => new { Type = "Success-Failure", Path = x }));

这不会像你想象的那样“短路”(因此它会发现所有路径冲突而不是在第一种类型之后停止),但它至少应该给你生成报告所需的数据。