LINQ 예제 코드를 보면 [ic]Select[/ic], [ic]SelectMany[/ic]가 빈번히 사용된다.
알면 쉽지만 헷갈리기 시작하면 한없이 헷갈린다.
이번 포스팅을 통해 확실하게 개념을 정리해보자.
예제용 리스트 생성
월드컵 우승 국가와 연도를 담은 리스트다.
List<Winner> list = new()
{
new Winner() { Country = "Argentina", Years = new[] { 1978, 1986, 2022 } },
new Winner() { Country = "England ", Years = new[] { 1966 } },
new Winner() { Country = "Germany ", Years = new[] { 1954, 1974, 1990, 2014 } },
};
Select 사용 예시
List<string> countries = list.Select(w => w.Country).ToList();
countries.ForEach(c => Console.WriteLine(c));
//output
Argentina
England
Germany
복잡한 객체가 담긴 리스트에서 원하는 부분을 손쉽게 추출하여 새로운 형태의 컬렉션을 생성한다.
(기존 컬렉션에 영향 X)
그런데! 뽑으려는 속성값이 배열이라면 [ic]Select[/ic]는 번거롭다.
List<int[]> listOfArrays = list.Select(w => w.Years).ToList();
listOfArrays.ForEach(y => Console.WriteLine(y));
//output
System.Int32[]
System.Int32[]
System.Int32[]
배열 안에 있는 값은 보이지 않고 타입명만 출력되기 때문이다.
해당 값들을 읽기 위해선 이중 for loop를 이용해야 한다. 상당히 번거롭다.
이때 [ic]SelectMany[/ic]를 사용하면 편리하다.
SelectMany 사용 예시
1) 파라미터 1개 있을 경우
List<int> aggregatedList = list.SelectMany(w => w.Years).ToList();
aggregatedList.ForEach(y => Console.WriteLine(y));
//output
1978
1986
2022
1966
1954
1974
1990
2014
[ic]이중 for loop[/ic] 없이 리스트 안에 값을 풀어 하나의 컬렉션으로 만든다.
하지만 이렇게 풀어 헤치기만 하면 어느 국가에 우승 연도인지 파악이 안된다.
이때 파라미터 2개를 사용하면 문제를 해결할 수 있다.
2) 파라미터 2개 있을 경우
var customList = list.SelectMany(w => w.Years, (w, y) => new { Country = w.Country, Year = y}).ToList();
복잡하고 낯선 형태다. 하나씩 분석해 보자.
[ic]w[/ic]는 [ic]Winner[/ic]객체가 넘어오는 자리다.
[ic]w => w.Years[/ic]를 통해 풀어헤친 [ic]Year 배열[/ic]이 [ic]y[/ic]로 통과된다.
그럼 새롭게 생성된 [ic]new { Country = w.Country, year =y } [/ic] 는 어떤 모습일까?
결과는 아래와 같다.
customList.ForEach(e => Console.WriteLine(e));
//output
{ Country = Argentina, Year = 1978 }
{ Country = Argentina, Year = 1986 }
{ Country = Argentina, Year = 2022 }
{ Country = England , Year = 1966 }
{ Country = Germany , Year = 1954 }
{ Country = Germany , Year = 1974 }
{ Country = Germany , Year = 1990 }
{ Country = Germany , Year = 2014 }
결과를 보면 어떻게 동작하는지 감이 올 거다.
이 글과 읽으면 좋은글
'c#' 카테고리의 다른 글
C# 필드(Field) vs. 프로퍼티(Property) 차이 비교 (3) | 2023.12.07 |
---|---|
[c# LINQ] Orderby vs ThenBy 차이 (0) | 2023.03.20 |
[c# ] 필드 | 프러퍼티 앞에 붙어 있는 required는 뭘까? (0) | 2023.03.13 |
[c# EntityFramework] dbcontext 마이그레이션 롤백하는 방법 (0) | 2023.02.28 |
[c#] json 파싱하는법 (0) | 2023.02.23 |
댓글