c# distinct - 한 List<>에서 다른 List<>에없는 항목을 가져 오려면 LINQ를 사용하십시오.




.net-3.5 (8)

구직자가 아직 가지고 있지 않은 IT 기술을 습득 한 실제 예가 있습니다.

//Get a list of skills from the Skill table
IEnumerable<Skill> skillenum = skillrepository.Skill;
//Get a list of skills the candidate has                   
IEnumerable<CandSkill> candskillenum = candskillrepository.CandSkill
       .Where(p => p.Candidate_ID == Candidate_ID);             
//Using the enum lists with LINQ filter out the skills not in the candidate skill list
IEnumerable<Skill> skillenumresult = skillenum.Where(p => !candskillenum.Any(p2 => p2.Skill_ID == p.Skill_ID));
//Assign the selectable list to a viewBag
ViewBag.SelSkills = new SelectList(skillenumresult, "Skill_ID", "Skill_Name", 1);

이 작업을 수행하기위한 간단한 LINQ 쿼리가 있다고 가정하고, 정확히 어떻게 확신 할 수는 없습니다. 아래의 코드 스 니펫을 참조하십시오.

class Program
{
    static void Main(string[] args)
    {
        List<Person> peopleList1 = new List<Person>();
        peopleList1.Add(new Person() { ID = 1 });
        peopleList1.Add(new Person() { ID = 2 });
        peopleList1.Add(new Person() { ID = 3 });

        List<Person> peopleList2 = new List<Person>();
        peopleList2.Add(new Person() { ID = 1 });
        peopleList2.Add(new Person() { ID = 2 });
        peopleList2.Add(new Person() { ID = 3 });
        peopleList2.Add(new Person() { ID = 4 });
        peopleList2.Add(new Person() { ID = 5 });
    }
}

class Person
{
    public int ID { get; set; }
}

peopleList2 에없는 peopleList2 모든 사람들에게 LINQ 쿼리를 수행하여이 예제에서 두 사람 (ID = 4 및 ID = 5)을 제공해야합니다.


Klaus의 답변은 훌륭했지만 ReSharper는 "LINQ 표현을 단순화"하도록 요청할 것입니다.

var result = peopleList2.Where(p => peopleList1.All(p2 => p2.ID != p.ID));


또는 부정하지 않고 원할 경우 :

var result = peopleList2.Where(p => peopleList1.All(p2 => p2.ID != p.ID));

기본적으로 peopleList1의 모든 ID가 peoplesList2의 id와 다른 peopleList2를 모두 얻습니다.

수락 된 대답에서 조금 다른 접근법 :)


당신이 사람의 평등을 무시한다면 당신은 또한 다음을 사용할 수 있습니다 :

peopleList2.Except(peopleList1)

두 번째 목록을 해시 테이블에 넣을 수 있으므로 Where(...Any) 변형보다 훨씬 빠르게해야합니다. HashSet<T> (거의)을 기반으로하는 변형은 O(peopleList1.Count + peopleList2.Count) 의 런타임을 갖는 반면, Where(...Any)O(peopleList1.Count * peopleList2.Count) 의 런타임 O(peopleList1.Count + peopleList2.Count) .

Except 암시 적으로 중복을 제거합니다. 귀하의 사례에 영향을 미치지 않아야하지만 비슷한 경우에는 문제가 될 수 있습니다.

또는 빠른 코드를 원하지만 동일성을 무시하고 싶지 않은 경우 :

var excludedIDs = new HashSet<int>(peopleList1.Select(p => p.ID));
var result = peopleList2.Where(p => !excludedIDs.Contains(p.ID));

이 변형은 중복을 제거하지 않습니다.


비트 파티에 늦었지만 또한 Linq SQL 호환되는 좋은 솔루션입니다 :

List<string> list1 = new List<string>() { "1", "2", "3" };
List<string> list2 = new List<string>() { "2", "4" };

List<string> inList1ButNotList2 = (from o in list1
                                   join p in list2 on o equals p into t
                                   from od in t.DefaultIfEmpty()
                                   where od == null
                                   select o).ToList<string>();

List<string> inList2ButNotList1 = (from o in list2
                                   join p in list1 on o equals p into t
                                   from od in t.DefaultIfEmpty()
                                   where od == null
                                   select o).ToList<string>();

List<string> inBoth = (from o in list1
                       join p in list2 on o equals p into t
                       from od in t.DefaultIfEmpty()
                       where od != null
                       select od).ToList<string>();

http://www.dotnet-tricks.com/Tutorial/linq/UXPF181012-SQL-Joins-with-C 명성


Enumerable Extension을 사용하면 제외 할 항목 목록과 비교를 수행하는 데 사용할 키를 찾는 데 사용할 함수를 정의 할 수 있습니다.

public static class EnumerableExtensions
{
    public static IEnumerable<TSource> Exclude<TSource, TKey>(this IEnumerable<TSource> source,
    IEnumerable<TSource> exclude, Func<TSource, TKey> keySelector)
    {
       var excludedSet = new HashSet<TKey>(exclude.Select(keySelector));
       return source.Where(item => !excludedSet.Contains(keySelector(item)));
    }
}

이런 식으로 사용할 수 있습니다.

list1.Exclude(list2, i => i.ID);

var result = peopleList2.Where(p => !peopleList1.Any(p2 => p2.ID == p.ID));

일반 저장소를 사용하는 경우

> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Rank}).ToList();

그밖에

> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();






c# linq .net-3.5