SelectMany 메서드?
- 컬렉션 속성을 가지고 있는 객체가 있고, 자식 컬렉션의 각 항목을 하나씩 열거해야하는 경우 사용하는 메서드
- 쉽게 설명하면 Collection안에 다른 Collection이 정의되어 있고, 이 중 Sub Collection의 데이터를 가져올때 사용하는 메서드이다.
Select 메서드
- Select 메서드는 객체에 담긴 데이터 중 원하는 값만 추출하여 새로운 형태의 컬렉션을 생성하는 메서드이다.
- 아래의 예시는 Team 객체에서 name 값만 추출하여 새로운 컬렉션을 만든 것이다.
class Program
{
public class Team
{
public string name;
public string[] players;
}
static void Main(string[] args)
{
List<Team> lst = new List<Team>()
{
new Team(){ name = "TeamA", players = new string[] { "Kim", "Lee" } },
new Team(){ name = "TeamB", players = new string[] { "Park", "Choi", "Yoon" } },
new Team(){ name = "TeamC", players = new string[] { "Song", "Oh" } }
};
// name만 추출
var teams = lst.Select(s => s.name).ToList();
foreach (string name in teams)
Console.WriteLine(name);
}
}
// 출력 결과
// TeamA
// TeamB
// TeamC
- 하지만 객체안에 데이터 중 컬렉션 형태로 저장되어있다면 2중 for문을 돌아야 값을 확인 할 수 있다.
- 아래 예시는 Team객체에서 players만 추출하여 새로운 컬렉션을 만든 예시이다.
class Program
{
public class Team
{
public string name;
public string[] players;
}
static void Main(string[] args)
{
List<Team> lst = new List<Team>()
{
new Team(){ name = "TeamA", players = new string[] { "Kim", "Lee" } },
new Team(){ name = "TeamB", players = new string[] { "Park", "Choi", "Yoon" } },
new Team(){ name = "TeamC", players = new string[] { "Song", "Oh" } }
};
// players만 추출
var PlayerList = lst.Select(s => s.players).ToList();
foreach (string[] players in PlayerList)
foreach (string player in players)
Console.WriteLine(player);
}
}
// 출력 결과
// Kim
// Lee
// Park
// Choi
// Yoon
// Song
// Oh
SelectMany 메서드
- SelectMany 메서드를 사용하면 객체안에 있는 컬렉션 형태의 데이터를 하나의 컬렉션으로 합쳐준다.
- Select 예시와 동일하게 players만 추출했지만 Select때와 달리 하나의 컬렉션에 담겨 for문 한번만으로 모든 값이 출력 되는 것을 볼 수 있다.
class Program
{
public class Team
{
public string name;
public string[] players;
}
static void Main(string[] args)
{
List<Team> lst = new List<Team>()
{
new Team(){ name = "TeamA", players = new string[] { "Kim", "Lee" } },
new Team(){ name = "TeamB", players = new string[] { "Park", "Choi", "Yoon" } },
new Team(){ name = "TeamC", players = new string[] { "Song", "Oh" } }
};
// players를 하나의 컬렉션으로 합쳐줌
var PlayerList = lst.SelectMany(s => s.players).ToList();
foreach (string player in PlayerList)
Console.WriteLine(player);
}
}
// 출력 결과
// Kim
// Lee
// Park
// Choi
// Yoon
// Song
// Oh
- 이외에 SelectMany의 유용한 점은 좀 더 복잡한 형태로도 변형이 가능하다는 점이다.
- 아래의 예제에서 SelectMany를 사용한 구문을 보면 lst의 각 객체를 team으로 하고, team에서 players만 추출한다.
그럼 다음 (team, player)에서 첫번째 변수는 lst에서 추출한 team이, 두번째 변수는 team에서 추출한 players들의 컬렉션이 들어가게된다. - 객체의 값을 뽑아 새로운 익명 클래스를 만들었다.
class Program
{
public class Team
{
public string name;
public string[] players;
}
static void Main(string[] args)
{
List<Team> lst = new List<Team>()
{
new Team(){ name = "TeamA", players = new string[] { "Kim", "Lee" } },
new Team(){ name = "TeamB", players = new string[] { "Park", "Choi", "Yoon" } },
new Team(){ name = "TeamC", players = new string[] { "Song", "Oh" } }
};
// 복잡한 형태로 변형
var playerList = lst.SelectMany(team => team.players, (team, player) => new { name = team.name, player = player }).ToList();
foreach (var p in playerList)
Console.WriteLine(p);
}
}
// 출력 결과
// { name = TeamA, player = Kim }
// { name = TeamA, player = Lee }
// { name = TeamB, player = Park }
// { name = TeamB, player = Choi }
// { name = TeamB, player = Yoon }
// { name = TeamC, player = Song }
// { name = TeamC, player = Oh }
- 메서드 구문과 쿼리구문을 함께 보면 이해하기가 좀 더 쉽고 생각한다.
- SelectMany 메서드를 사용한 것(Method Synatax)과 from문을 두번 사용한 것(Query Syntax)과 동일하게 작동한다.
class Program
{
public class Team
{
public string name;
public string[] players;
}
static void Main(string[] args)
{
List<Team> lst = new List<Team>()
{
new Team(){ name = "TeamA", players = new string[] { "Kim", "Lee" } },
new Team(){ name = "TeamB", players = new string[] { "Park", "Choi", "Yoon" } },
new Team(){ name = "TeamC", players = new string[] { "Song", "Oh" } }
};
// 메서드 구문 (Method Syntax)
var playerList = lst.SelectMany(team => team.players, (team, player) => new { name = team.name, player = player }).ToList();
Console.WriteLine("메서드 구문");
foreach (var p in playerList)
Console.WriteLine(p);
// 쿼리 구문 (Query Syntax)
var playerList2 = (from team in lst
from player in team.players
select new
{
name = team.name,
player = player
}).ToList();
Console.WriteLine("\n쿼리 구문");
foreach (var p in playerList2)
Console.WriteLine(p);
}
}
// 출력 결과
// 메서드 구문
// { name = TeamA, player = Kim }
// { name = TeamA, player = Lee }
// { name = TeamB, player = Park }
// { name = TeamB, player = Choi }
// { name = TeamB, player = Yoon }
// { name = TeamC, player = Song }
// { name = TeamC, player = Oh }
//
// 쿼리 구문
// { name = TeamA, player = Kim }
// { name = TeamA, player = Lee }
// { name = TeamB, player = Park }
// { name = TeamB, player = Choi }
// { name = TeamB, player = Yoon }
// { name = TeamC, player = Song }
// { name = TeamC, player = Oh }
두가지 방법 다 같은 익명 클래스를 만들어진 것을 알 수 있다.
이 처럼 SelectMany 메서드는 객체안의 Collection 속성을 한번에 정리하는 기능과 그 값들을 좀 더 복잡한 형태로도 변형하는 기능이 있다.
'C# > Enumerable (Linq)' 카테고리의 다른 글
[C#] Enumerable.Any(), Enumerable.All() 메서드 (0) | 2025.01.08 |
---|---|
[C#] OfType<T>() vs CAST<T>() (0) | 2024.12.19 |
[C#] Enumerable.Union() 메서드 (0) | 2024.12.13 |
[C#] Enumerable.FirstOrDefault() 메서드 (0) | 2024.12.10 |
[C#] Linq (람다식 메서드) (0) | 2024.11.05 |