샘플 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 } },
};
적용 사례 선택
List<string> countries = list.Select(w => w.Country).ToList();
countries.ForEach(c => Console.WriteLine(c));
//output
Argentina
England
Germany
복잡한 객체 목록에서 원하는 부분을 간단히 추출하여 새로운 유형의 컬렉션을 만듭니다.
(기존 컬렉션에는 영향 없음)
하지만! 선택할 속성 값이 배열인 경우 (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 루프를 사용해야 합니다. 꽤 어색합니다.
이 경우 (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 루프(/ic) 없이 목록의 값을 풀고 모음을 만듭니다.
그런데 그렇게만 풀면 어느 나라가 그 해를 이겼는지 알 수가 없습니다.
이 경우 두 개의 매개변수를 사용하면 문제를 해결할 수 있습니다.
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 }
결과는 작동 방식에 대한 느낌을 제공합니다.
