Lookup
Lookup<TKey, TElement>
는 .NET에서 제공하는 특수한 컬렉션으로, 하나의 키에 여러 개의 값을 매핑할 수 있는 구조를 제공합니다. 이는 SQL의 GROUP BY
와 유사한 기능을 제공하여, 키를 기준으로 여러 요소를 그룹화할 때 유용합니다. Lookup
컬렉션은 읽기 전용이며, 그룹화된 데이터를 조회하는 데 최적화되어 있습니다.
Lookup 특징
- 다중 값 매핑:
Lookup
은 하나의 키에 여러 개의 값을 연결할 수 있으며, 이를 통해 다중 값을 효율적으로 관리할 수 있습니다. 예를 들어, 같은 카테고리에 속하는 여러 개의 제품을 한 번에 저장하고 조회할 수 있습니다. - 읽기 전용:
Lookup
컬렉션은 변경할 수 없으며, 데이터를 생성한 후에는 추가, 삭제, 수정이 불가능합니다. 이로 인해 스레드 안전성을 제공하며 읽기 전용 시나리오에 적합합니다. - 빠른 조회: 내부적으로 해시 테이블을 사용하여 키에 대한 빠른 조회 성능을 제공합니다. 따라서 많은 데이터를 그룹화하고 검색해야 하는 경우 적합합니다.
장점
- 그룹화된 데이터 관리: 동일한 키에 여러 개의 요소를 저장하고 그룹화하여 관리할 수 있습니다. 이는 데이터 분석이나 보고서를 생성할 때 매우 유용합니다.
- 간편한 데이터 조회: 해시 테이블 기반으로 구현되어 있어, 키에 대한 빠른 검색이 가능합니다.
- LINQ와의 긴밀한 통합: LINQ의
ToLookup
을 통해 데이터를 쉽게 변환할 수 있으며, 익숙한 구문으로 컬렉션을 생성하고 조회할 수 있습니다.
단점
- 읽기 전용: 생성된 후에는 데이터를 추가하거나 수정할 수 없습니다. 따라서 데이터가 변경되어야 하는 경우에는 적합하지 않습니다.
- 복잡한 생성 과정:
Lookup
은 직접 생성할 수 없고ToLookup
메서드를 통해서만 생성이 가능하기 때문에, 생성 과정이 다소 복잡할 수 있습니다. - 메모리 사용량:
Lookup
은 해시 테이블을 사용하여 내부적으로 키와 값을 매핑하므로, 다수의 키를 처리할 때 메모리 사용량이 늘어날 수 있습니다.
기본 사용법
Lookup
은 직접 생성자를 호출하여 만들 수 없으며, 대신 LINQ의 ToLookup
메서드를 사용하여 생성합니다. 이를 통해 컬렉션을 특정 키로 그룹화하여 Lookup
객체를 얻을 수 있습니다.
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
var products = new List<Product>
{
new Product { Category = "Fruit", Name = "Apple" },
new Product { Category = "Fruit", Name = "Banana" },
new Product { Category = "Vegetable", Name = "Carrot" },
new Product { Category = "Vegetable", Name = "Broccoli" },
new Product { Category = "Fruit", Name = "Strawberry" }
};
// ToLookup을 사용하여 제품을 카테고리별로 그룹화
var productLookup = products.ToLookup(p => p.Category);
// 각 카테고리에 속하는 제품들을 출력
foreach (var group in productLookup)
{
Console.WriteLine($"Category: {group.Key}");
foreach (var product in group)
{
Console.WriteLine($" {product.Name}");
}
}
}
}
class Product
{
public string Category { get; set; }
public string Name { get; set; }
}
ToLookup
을 사용하여Product
리스트를Category
기준으로 그룹화했습니다.- 각 키에 대해 연결된 여러 요소들을 반복문을 통해 쉽게 접근할 수 있습니다.
주요 메서드와 프로퍼티
Count
:Lookup
에 포함된 그룹의 수를 반환합니다. 각 키에 대한 그룹을 몇 개 가지고 있는지 확인할 수 있습니다.
int groupCount = productLookup.Count;
Contains(TKey key)
: 특정 키가Lookup
에 존재하는지 확인합니다.
bool hasFruitCategory = productLookup.Contains("Fruit");
Item[TKey key]
: 주어진 키에 대한 그룹을 반환합니다. 인덱서를 통해 각 키에 연결된 요소들에 접근할 수 있습니다.
var fruits = productLookup["Fruit"];
foreach (var fruit in fruits)
{
Console.WriteLine(fruit.Name);
}
GetEnumerator()
:Lookup
의 키-그룹 쌍을 열거할 수 있는 열거자를 반환합니다. 이를 통해 모든 그룹을 순회할 수 있습니다.
foreach (var group in productLookup)
{
Console.WriteLine($"Category: {group.Key}");
}
Keys
:Lookup
에 있는 모든 키를 반환합니다. 이 프로퍼티는 데이터의 모든 키에 접근할 수 있게 해줍니다.
foreach (var key in productLookup.Select(g => g.Key)) { Console.WriteLine($“Key: {key}”); }
이 메서드와 프로퍼티들은 `Lookup` 컬렉션의 데이터를 그룹화하고, 그룹에 접근하거나 특정 키의 존재 여부를 확인하는 데 매우 유용합니다. 이를 활용해 데이터의 탐색, 분석, 그룹화가 간편해집니다.
## 활용 사례
- 데이터 분석: `Lookup`은 동일한 키를 가진 여러 데이터를 그룹화할 수 있으므로, 데이터 분석에서 특정 기준으로 데이터를 그룹화하여 처리하는 데 유용합니다.
- 보고서 생성: 예를 들어, 고객의 주문 내역을 주문 날짜 또는 카테고리별로 그룹화할 때 사용할 수 있습니다.
- 빠른 검색 기능: 하나의 키에 대해 다수의 값을 검색해야 하는 상황에서 효율적으로 사용할 수 있습니다.
## 한계
- 변경 불가능: 생성 후 데이터를 추가하거나 수정할 수 없기 때문에, 실시간으로 변경이 필요한 데이터 관리에는 부적합합니다.
- 비교적 높은 메모리 사용: `Lookup`은 내부적으로 [HashTable](/dotnet/자료구조/비제네릭-컬렉션#hashtable)을 사용하므로, 많은 양의 데이터를 처리할 때 메모리 사용이 증가할 수 있습니다.
`Lookup`은 효율적인 데이터 그룹화와 검색을 제공하지만, 변경이 필요한 상황에서는 다른 대안을 고려해야 합니다. 대규모 데이터셋에서 데이터를 분류하고 정리하는 용도로는 매우 적합하지만, 실시간 데이터 변경이 필요할 때는 다른 컬렉션과 조합하여 사용하는 것이 좋습니다.