본문 바로가기
프로그래밍/C# LINQ

C# Select vs SelectMany

by bantomak 2023. 6. 19.
반응형

Select() 메서드

객체에 담긴 여러 데이터 중에서 원하는 부분만 손쉽게 추출하여 새로운 형태의 컬렉션으로 생성한다.

public class Program
{
    public class Winner
    {
        public string name;
        public int[] years;
    }

    public static void Main()
    {
        List<Winner> list = new()
        {
            new Winner() { name = "Boston", years = new [] { 1989, 1999 } },
            new Winner() { name = "Yankees", years = new [] { 2000, 2012, 2013, 2018 } },
            new Winner() { name = "Newyork", years = new [] { 1934, 2021, 2022 } },
        };

        List<string> teamName = list.Select(l => l.name).ToList();
        teamName.ForEach(c => Console.WriteLine(c));
    }
}

팀명
정상적으로 팀 이름이 출력되었다.

 

원하는 팀 이름을 뽑았다. 하지만 출력하려는 컬렉션이 배열이라면 복잡한 상황이 발생한다.

public class Program
{
    public class Winner
    {
        public string name;
        public int[] years;
    }

    public static void Main()
    {
        List<Winner> list = new()
        {
            new Winner() { name = "Boston", years = new [] { 1989, 1999 } },
            new Winner() { name = "Yankees", years = new [] { 2000, 2012, 2013, 2018 } },
            new Winner() { name = "Newyork", years = new [] { 1934, 2021, 2022 } },
        };

        List<int[]> years = list.Select(l => l.years).ToList();
        years.ForEach(c => Console.WriteLine(c));
    }
}

에러
배열 안에 값은 안보이고 타입명만 출력된다.

 

public class Program
{
    public class Winner
    {
        public string name;
        public int[] years;
    }

    public static void Main()
    {
        List<Winner> list = new()
        {
            new Winner() { name = "Boston", years = new[] { 1989, 1999 } },
            new Winner() { name = "Yankees", years = new[] { 2000, 2012, 2013, 2018 } },
            new Winner() { name = "Newyork", years = new[] { 1934, 2021, 2022 } },
        };

        List<int[]> years = list.Select(l => l.years).ToList();

        foreach(var array in years)
        {
            foreach(var c in array)
            {
                Console.WriteLine(c);
            }
        }
    }
}

 

2중 for문으로 작성해야지 정상적으로 출력이 된다.

 

이제 정상적으로 연도가 출력된다.

 

SelectMany() 메서드

selectmany를 사용하면 리스트 안의 리스트를 평탄화한다.

 

public class Program
{
    public class Winner
    {
        public string name;
        public int[] years;
    }

    public static void Main()
    {
        List<Winner> list = new()
        {
            new Winner() { name = "Boston", years = new [] { 1989, 1999 } },
            new Winner() { name = "Yankees", years = new [] { 2000, 2012, 2013, 2018 } },
            new Winner() { name = "Newyork", years = new [] { 1934, 2021, 2022 } },
        };

        var years = list.SelectMany(l => l.years).ToList();
        years.ForEach(c => Console.WriteLine(c));
    }
}

selectmany로 평탄화되어서 2중 for문을 사용하지 않아도 된다.

 

노말
이제 정상적으로 연도가 출력된다.

 

SelectMany() 메서드 두 번째 예시

public class Program
{
    public class Winner
    {
        public string name;
        public int[] years;
    }

    public static void Main()
    {
        List<Winner> list = new()
        {
            new Winner() { name = "Boston", years = new [] { 1989, 1999 } },
            new Winner() { name = "Yankees", years = new [] { 2000, 2012, 2013, 2018 } },
            new Winner() { name = "Newyork", years = new [] { 1934, 2021, 2022 } },
        };

        var years = list.SelectMany(l => l.years, (l, y) => new { name = l.name, years = y}).ToList();
        years.ForEach(c => Console.WriteLine(c));
    }
}

보다 복잡한 형태로 컬렉션을 만들어서 출력할 수 있다.

 

 

SelectMany() 메서드 구현 예제

static IEnumerable<TOutput> SelectMany<T1, T2, TOutput>(
    this IEnumerable<T1> src,
    Func<T1, IEnumerable<T2>> inputSelector,
    Func<T1, T2, TOutput> resultSelector)
{
    foreach (T1 first in src)
    {
        foreach (T2 second in inputSelector(first))
        {
            yield return resultSelector(first, second);
        }
    }
}

 

함께 읽으면 좋은 글

 

C# 익명 타입 (Anonymous Type)

익명 타입이란? C#에서 어떤 클래스를 사용하기 위해서는 일반적으로 먼저 클래스를 정의한 후 사용한다. 하지만 C# 3.0부터 클래스를 미리 정의하지 않고 사용할 수 있게 하는 익명 타입(Anonymous T

jettstream.tistory.com

 

Difference Between Select and SelectMany

I've been searching the difference between Select and SelectMany but I haven't been able to find a suitable answer. I need to learn the difference when using LINQ To SQL but all I've found are stan...

stackoverflow.com

'프로그래밍 > C# LINQ' 카테고리의 다른 글

C# Linq - Enumerable.Range()  (0) 2023.12.18
C# Linq - Enumerable.Aggregate()  (19) 2023.06.26
C# Linq - Enumerable.OrderBy()  (26) 2023.06.20
C# Linq - Enumerable.Repeat()  (26) 2023.06.13
C# Linq - Enumerable.Join()  (12) 2023.04.20

댓글