본문 바로가기
카테고리 없음

C# LINQ 고급 기능 완벽 정리 🚀

by bbongz 2025. 3. 7.

 

이전 글에서 LINQ의 기본 개념과 사용법을 배웠다면, 이제 한 단계 더 나아가 고급 기능을 알아볼 차례입니다.
LINQ를 잘 활용하면 데이터 필터링, 그룹화, 조인, 변환 등을 간결한 코드로 처리할 수 있어요!

이번 글에서는 LINQ의 고급 기능쉽고 실용적인 코드 예제와 함께 배워봅시다.


🔥 1. SelectMany() – 중첩 리스트 펼치기

Select()는 개별 요소를 변환하지만, SelectMany()는 중첩된 컬렉션(List 안의 List)한 개의 리스트로 평탄화 합니다.

✅ 기본 예제: 중첩 리스트를 하나의 리스트로 변환

List<List<int>> numbers = new List<List<int>>
{
    new List<int> { 1, 2, 3 },
    new List<int> { 4, 5 },
    new List<int> { 6, 7, 8, 9 }
};

// Select 사용 (중첩 리스트 유지)
var selectResult = numbers.Select(list => list);

// SelectMany 사용 (모든 숫자를 하나의 리스트로)
var selectManyResult = numbers.SelectMany(list => list);

Console.WriteLine("Select 사용:");
foreach (var list in selectResult)
{
    Console.WriteLine($"리스트: {string.Join(", ", list)}");
}

Console.WriteLine("\nSelectMany 사용:");
Console.WriteLine(string.Join(", ", selectManyResult));

📝 실행 결과

Select 사용:
리스트: 1, 2, 3  
리스트: 4, 5  
리스트: 6, 7, 8, 9  

SelectMany 사용:
1, 2, 3, 4, 5, 6, 7, 8, 9  

💡 핵심 포인트

  • Select() → 중첩된 리스트를 그대로 유지
  • SelectMany() → 모든 리스트를 하나의 리스트로 펼침

🔥 2. Join() – 두 개의 리스트 연결하기

LINQ의 Join()을 사용하면 두 개의 컬렉션을 특정 키를 기준으로 결합할 수 있습니다.
SQL의 INNER JOIN과 같은 역할을 합니다.

✅ 기본 예제: 학생과 점수 데이터 결합

class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Score
{
    public int StudentId { get; set; }
    public int ScoreValue { get; set; }
}

List<Student> students = new List<Student>
{
    new Student { Id = 1, Name = "Alice" },
    new Student { Id = 2, Name = "Bob" },
    new Student { Id = 3, Name = "Charlie" }
};

List<Score> scores = new List<Score>
{
    new Score { StudentId = 1, ScoreValue = 85 },
    new Score { StudentId = 2, ScoreValue = 92 }
};

// 학생과 점수 데이터를 ID(StudentId) 기준으로 연결
var studentScores = students.Join(
    scores,
    student => student.Id,    // 첫 번째 컬렉션의 키
    score => score.StudentId, // 두 번째 컬렉션의 키
    (student, score) => new { student.Name, score.ScoreValue }
);

foreach (var item in studentScores)
{
    Console.WriteLine($"{item.Name}의 점수: {item.ScoreValue}");
}

📝 실행 결과

Alice의 점수: 85  
Bob의 점수: 92  

💡 핵심 포인트

  • students.Join(scores, student => student.Id, score => score.StudentId, ...)
    • 두 개의 리스트를 ID를 기준으로 결합
  • Charlie는 점수가 없어서 결과에 없음 (INNER JOIN 동작)

🔥 3. GroupBy() – 데이터 그룹화

GroupBy()를 사용하면 특정 기준으로 데이터를 그룹화할 수 있습니다.

✅ 기본 예제: 학생을 학년별로 그룹화

class Student
{
    public string Name { get; set; }
    public int Grade { get; set; }
}

List<Student> students = new List<Student>
{
    new Student { Name = "Alice", Grade = 1 },
    new Student { Name = "Bob", Grade = 2 },
    new Student { Name = "Charlie", Grade = 1 },
    new Student { Name = "David", Grade = 3 },
    new Student { Name = "Eve", Grade = 2 }
};

// 학년별 그룹화
var groupedStudents = students.GroupBy(s => s.Grade);

foreach (var group in groupedStudents)
{
    Console.WriteLine($"학년 {group.Key} 학생들:");
    foreach (var student in group)
    {
        Console.WriteLine($" - {student.Name}");
    }
}

📝 실행 결과

학년 1 학생들:  
 - Alice  
 - Charlie  

학년 2 학생들:  
 - Bob  
 - Eve  

학년 3 학생들:  
 - David  

💡 핵심 포인트

  • GroupBy(s => s.Grade) → 학년(Grade) 기준으로 그룹화
  • group.Key → 그룹의 기준값 (학년)

🔥 4. Aggregate() – 리스트 값 누적 연산

Aggregate()는 리스트의 값을 누적해서 하나의 값으로 변환할 때 사용합니다.

✅ 기본 예제: 숫자 리스트의 곱 구하기

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

// 모든 숫자의 곱 계산
int product = numbers.Aggregate((total, next) => total * next);

Console.WriteLine($"모든 숫자의 곱: {product}");

📝 실행 결과

모든 숫자의 곱: 120  

💡 핵심 포인트

  • Aggregate((total, next) => total * next)
    • total: 현재까지 계산된 값
    • next: 리스트의 다음 값

🔥 5. Distinct(), Union(), Intersect(), Except() – 집합 연산

LINQ는 리스트 간의 중복 제거, 합집합, 교집합, 차집합 연산도 지원합니다.

List<int> list1 = new List<int> { 1, 2, 3, 4, 5 };
List<int> list2 = new List<int> { 3, 4, 5, 6, 7 };

Console.WriteLine("Distinct (중복 제거):");
Console.WriteLine(string.Join(", ", list1.Distinct()));

Console.WriteLine("Union (합집합):");
Console.WriteLine(string.Join(", ", list1.Union(list2)));

Console.WriteLine("Intersect (교집합):");
Console.WriteLine(string.Join(", ", list1.Intersect(list2)));

Console.WriteLine("Except (차집합):");
Console.WriteLine(string.Join(", ", list1.Except(list2)));

📝 실행 결과

Distinct (중복 제거):  
1, 2, 3, 4, 5  

Union (합집합):  
1, 2, 3, 4, 5, 6, 7  

Intersect (교집합):  
3, 4, 5  

Except (차집합):  
1, 2  

✨ 마무리

이번 글에서는 LINQ의 고급 기능을 실전 예제와 함께 알아봤습니다.
이제 LINQ를 활용해 더 강력하고 직관적인 C# 코드를 작성할 수 있겠죠? 😃

 

📌 다음 글에서는 아래 내용을 다뤄볼게요!

  • LINQ와 Entity Framework 연동하기
  • 성능 최적화를 위한 LINQ 활용법