如何获得不同的元素?

时间:2013-06-06 02:40:28

标签: c# linq lambda

我在

下有一个班级
class WarningClass
    {
        public string SqlEyeWarning { get; set; }
        public string FileName { get; set; }
    }

它填充在

List<WarningClass> lstWarningClass1 = new List<WarningClass>();
lstWarningClass1.Add(new WarningClass { FileName = "a.sql", SqlEyeWarning = "SD001: order mismatch or it should be ON." });
lstWarningClass1.Add(new WarningClass { FileName = "a.sql", SqlEyeWarning = "SD001: order mismatch or it should be ON." });
lstWarningClass1.Add(new WarningClass { FileName = "c.sql", SqlEyeWarning = "SD009: Missing or order mismatch of Grant statement." });

可以看出第一和第二条记录有重复的条目。

如何获得唯一条目。

最终输出

FileName = "a.sql", SqlEyeWarning = "SD001: order mismatch or it should be ON." 
FileName = "c.sql", SqlEyeWarning = "SD009: Missing or order mismatch of Grant statement."

如果我执行lstWarningClass1.Distinct(),则无效

3 个答案:

答案 0 :(得分:3)

Linq的Distinct()在其描述中有以下内容:

默认的相等比较器Default用于比较实现 IEquatable泛型接口的类型的值。要比较自定义数据类型,您需要实现此接口并为该类型提供自己的GetHashCode和Equals方法。

粗体部分和Distinct()是否有效。

答案 1 :(得分:1)

您可以使用IEnumerable.GroupBy按照您关注的条件对列表中的对象进行分组。然后,您可以选择每个组的第一个元素。

您可以按FileName进行分组:

lstWarningClass1.GroupBy(w => w.FileName).Select(g => g.First())

FileNameSqlEyeWarning如此:

lstWarningClass1.GroupBy(w => new {w.FileName, w.SqlEyeWarning}).Select(g => g.First())

答案 2 :(得分:1)

您需要创建自定义IEqualityComparer<T>

public class CustomComparer : IEqualityComparer<WarningClass>
{
    public bool Equals(WarningClass x, WarningClass y)
    {
        return x.SqlEyeWarning.Equals(y.SqlEyeWarning)
               && x.FileName.Equals(y.FileName);
    }

    public int GetHashCode(WarningClass obj)
    {
        return obj.FileName.GetHashCode() 
            ^ obj.SqlEyeWarning.GetHashCode();
    }
}

然后使用自定义比较器调用重载的Distinct方法:

var result = lstWarningClass1.Distinct(new CustomComparer());