使用LINQ获取唯一对象

时间:2013-02-28 10:09:30

标签: linq

我有一个人类:

Public Class Person
{
public string Name {get; set;}
public string Id {get; set;}
}

Public EqualityOnPerson : IEqualityComparer<Person>
{
public bool Equals(PersonData x, PersonData y)
    {
        return x.Id == y.Id;
    }

    public int GetHashCode(Person obj)
    {
        return obj.Id.GetHashCode();
    }

}

我有一个包含重复ID的人物对象列表:

Person.Name = "ABC"
Person.Id = "123"

Person.Name = "CBA"
Person.Id = "123"

Person.Name = "DEF"
Person.Id = "456"

Person.Name = "GHI"
Person.Id = "789"

Person.Name = "JKL"
Person.Id = "789"

Person.Name = "MNO"
Person.Id = "789"

Person.Name = "PQR"
Person.Id = "101"

Person.Name = "STU"
Person.Id = "102"

使用distinct会给出

Person.Name = "CBA"
Person.Id = "123"

Person.Name = "DEF"
Person.Id = "456"

Person.Name = "GHI"
Person.Id = "789"

Person.Name = "PQR"
Person.Id = "101"

Person.Name = "STU"
Person.Id = "102"

我如何得到这个

Person.Name = "DEF"
Person.Id = "456"

Person.Name = "PQR"
Person.Id = "101"

Person.Name = "STU"
Person.Id = "102"

仅限那些没有重复的人物。

问候。

2 个答案:

答案 0 :(得分:2)

您需要使用相等比较器对人员进行分组,然后从只有一个人的群组中选择人员:

var unduplicatedPersons = persons
    .GroupBy(p => p, new EqualityOnPerson())
    .Where(g => g.Count() == 1)
    .Select(g => g.Key);

这是一种专用的扩展方法,如果需要可能会有轻微的性能优势(只是为了好玩):

public IEnumerable<T> DistinctOnly<T>(this IEnumerable<T> source,
                                      IEqualityComparer<T> comparer)
{
    HashSet<T> all = new HashSet<T>(comparer);
    HashSet<T> distinct = new HashSet<T>(comparer);
    foreach (T t in source)
    {
        if (all.Add(t))
            distinct.Add(t);
        else
            distinct.Remove(t);
    }
    return distinct;
}

答案 1 :(得分:0)

var result = persons.Where(outer => 
     persons.Count(inner => inner.Id == outer.Id ) < 2)

这样您就不需要相等比较器了。