프로그래밍/C#

[C#] LINQ 이용하여 리스트 2개 비교

Victory_HA 2022. 3. 22. 21:12

  • Linq에는 두 목록을 비교하는 유용한 방법이 있습니다.

Intersect

  • 리스트의 어떤 요소가 포함되어 있는지 확인할 수 있습니다.
    var source = new List<string>() { "a", "b", "c" };
    var compare = new List<string>() { "b", "c", "d" };
    var result = source.Intersect(compare);

결과

Except

  • 리스트에 포함되지 않은 요소를 확인할 수 있습니다.
    var source = new List<string>() { "a", "b", "c" };
    var compare = new List<string>() { "b", "c", "d" };
    var result = source.Except(compare);

결과

예외사항

  • 아래 예제처럼 Person Class의 요소를 비교하려고 할 때,
  • 단순히 Intersect, Except로는 값을 비교할 수 없습니다.
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
var source = new List<Person>() { new Person("stu1", "kim"), new Person("stu2", "john") };
var compare = new List<Person>() { new Person("stu2", "john"), new Person("stu3", "kenny") };

var res = source.Intersect(compare);    // 값이 안나온다.

해결1 - IntersectBy

  • .NET6부터 단순히 요소끼리 비교하려는 경우 IntersectBy로 비교 가능합니다.
    var result = source.IntersectBy(compare.Select(x => x.LastName), x => x.LastName);

해결2 - 비교자 생성

  • 위와 같은 경우 Person의 멤버변수를 불러와 비교하는 방법을 사용해야 합니다.
public class PersonComparer : IEqualityComparer<Person>
{
    public bool Equals(Person source, Person compare)
    {
        return source.LastName == compare.LastName;
    }
    public int GetHashCode(Person source)
    {
        return source.LastName.GetHashCode();
    }
}
var source = new List<Person>() { new Person("stu1", "kim"), new Person("stu2", "john") };
var compare = new List<Person>() { new Person("stu2", "john"), new Person("stu3", "kenny") };

//var res1 = source.Intersect(compare);
var res2 = source.Intersect(compare, new PersonComparer());

결과

다른 방법

  • where, count를 사용하여,
  • 중복되는 항목 & 중복되지 않는 항목을 구하는 방법을 알아봅시다.
var source = new List<Person>() 
{ 
    new Person("stu1", "kim"), 
    new Person("stu2", "john") 
};
var compare = new List<Person>() 
{ 
    new Person("stu2", "john"),
    new Person("stu3", "kenny") 
};

// 중복되는 값 찾기
var res1 = source.Where(x => compare.Count(s => x.LastName == s.LastName) != 0).ToList();

// 중복되지 않는 값 찾기
var res2 = source.Where(x => compare.Count(s => x.LastName == s.LastName) == 0).ToList();

결과