Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# LINQ의 Select와 SelectMany 차이점 완벽 정리

C# LINQ에서 SelectSelectMany는 모두 프로젝션(Projection) 연산자 범주에 속하지만, 결과를 반환하는 방식에서 중요한 차이가 있습니다.

Select 연산자란?

Select는 소스 시퀀스(source sequence)의 각 요소를 하나의 결과 값으로 변환(투영)합니다. 즉, 입력 요소 하나당 출력 요소 하나가 대응되며, 컬렉션 안에 컬렉션이 있는 구조라면 그대로 중첩된 형태로 유지됩니다.

SelectMany 연산자란?

SelectMany는 시퀀스의 각 요소를 IEnumerable<T>로 투영한 뒤, 그 결과로 만들어진 여러 시퀀스를 하나의 평면적인(flat) 시퀀스로 병합합니다. 중첩된 컬렉션을 단일 컬렉션으로 펼쳐야 할 때 매우 유용합니다.

예제 코드

아래 예제는 제품 카테고리와 해당 브랜드 목록을 담은 데이터를 SelectSelectMany로 각각 처리한 결과를 비교합니다.

class Demo
{
    public string Name { get; set; }
    public List<string> Contents { get; set; }

    public static List<Demo> GetAllContents()
    {
        List<Demo> listContents = new List<Demo>
        {
            new Demo
            {
                Name = "Cap",
                Contents = new List<string> { "Nike", "Adidas" }
            },
            new Demo
            {
                Name = "Shoes",
                Contents = new List<string> { "Nike", "Puma", "Adidas" }
            },
        };
        return listContents;
    }
}

class Program
{
    static void Main()
    {
        // Select: List<List<string>> 형태의 중첩 구조 유지
        IEnumerable<List<string>> result = Demo.GetAllContents().Select(s => s.Contents);
        foreach (List<string> stringList in result)
        {
            foreach (string str in stringList)
            {
                Console.WriteLine(str);
            }
        }

        Console.WriteLine("---Select Many---");

        // SelectMany: 중첩된 목록을 하나의 시퀀스로 평탄화
        IEnumerable<string> resultSelectMany = Demo.GetAllContents().SelectMany(s => s.Contents);
        foreach (string str in resultSelectMany)
        {
            Console.WriteLine(str);
        }

        Console.ReadKey();
    }
}

실행 결과

Nike
Adidas
Nike
Puma
Adidas
---Select Many---
Nike
Adidas
Nike
Puma
Adidas

핵심 차이점 요약

  • Select: 각 요소를 변환하여 IEnumerable<List<string>>처럼 중첩된 구조를 그대로 반환합니다. 내부 컬렉션을 순회하려면 이중 foreach문이 필요합니다.
  • SelectMany: 중첩된 컬렉션을 자동으로 평탄화하여 IEnumerable<string>처럼 단일 시퀀스를 반환합니다. 하나의 foreach문으로 바로 순회할 수 있습니다.

정리하면, 요소별 변환이 필요하면 Select를, 중첩된 컬렉션을 하나로 합쳐야 한다면 SelectMany를 사용하는 것이 올바른 선택입니다.