[C#] 특정 속성에 대한 LINQ의 Distinct ()

나는 LINQ와 함께 그것에 대해 배우고 있지만 Distinct간단한 목록이없는 경우 사용하는 방법을 알 수 없습니다 (간단한 정수 목록은 수행하기가 쉽습니다. 이것은 문제가 아닙니다). 나는 희망을 사용하는 경우는 어떻게 고유 의 개체 목록에 하나 개 또는 더 많은 개체의 속성?

예 : 객체 인 경우 Person속성, Id. 모든 Person을 얻고 객체 Distinct의 속성 Id으로 어떻게 사용할 수 있습니까?

Person1: Id=1, Name="Test1"
Person2: Id=1, Name="Test1"
Person3: Id=2, Name="Test2"

어떻게 난 그냥 얻을 수 Person1Person3? 가능합니까?

LINQ를 사용할 수 없다면 Person.NET 3.5의 일부 속성에 따라 목록을 작성하는 가장 좋은 방법은 무엇입니까?



답변

편집 : 이것은 이제 MoreLINQ의 일부입니다 .

당신이 필요로하는 것은 효과적으로 “별명”입니다. 작성하기가 쉽지만 LINQ의 일부라고 생각하지 않습니다.

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
    (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> seenKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (seenKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

Id속성 만 사용하여 고유 한 값을 찾으려면 다음을 사용할 수 있습니다.

var query = people.DistinctBy(p => p.Id);

여러 속성을 사용하려면 익명 유형을 사용하면 동등성을 적절하게 구현할 수 있습니다.

var query = people.DistinctBy(p => new { p.Id, p.Name });

테스트되지 않았지만 작동해야합니다 (그리고 이제 적어도 컴파일됩니다).

키에 대한 기본 비교자를 가정합니다. 만약 당신이 동등 비교기를 전달하고 싶다면, 그것을 HashSet생성자 에게 전달하십시오 .


답변

나는에 따라 별개의 목록을 얻기 위해 무엇을하려는 경우 하나 개 또는 더 많은 속성을?

단순한! 당신은 그들을 그룹화하고 그룹에서 승자를 선택합니다.

List<Person> distinctPeople = allPeople
  .GroupBy(p => p.PersonId)
  .Select(g => g.First())
  .ToList();

여러 속성에 그룹을 정의하려면 다음과 같이하십시오.

List<Person> distinctPeople = allPeople
  .GroupBy(p => new {p.PersonId, p.FavoriteColor} )
  .Select(g => g.First())
  .ToList();


답변

사용하다:

List<Person> pList = new List<Person>();
/* Fill list */

var result = pList.Where(p => p.Name != null).GroupBy(p => p.Id).Select(grp => grp.FirstOrDefault());

where당신이 항목을 필터링하는 데 도움이 (더 복잡 할 수있다)과 groupby와는 select별개의 기능을 수행한다.


답변

모든 LINQ와 같이 보이게하려면 쿼리 구문을 사용할 수도 있습니다.

var uniquePeople = from p in people
                   group p by new {p.ID} //or group by new {p.ID, p.Name, p.Whatever}
                   into mygroup
                   select mygroup.FirstOrDefault();


답변

충분하다고 생각합니다.

list.Select(s => s.MyField).Distinct();


답변

솔루션을 먼저 필드별로 그룹화 한 다음 firstordefault 항목을 선택하십시오.

    List<Person> distinctPeople = allPeople
   .GroupBy(p => p.PersonId)
   .Select(g => g.FirstOrDefault())
   .ToList();


답변

표준으로이 작업을 수행 할 수 있습니다 Linq.ToLookup(). 각 고유 키에 대한 값 모음이 생성됩니다. 컬렉션에서 첫 번째 항목을 선택하십시오.

Persons.ToLookup(p => p.Id).Select(coll => coll.First());