미션 5: 람다와 LINQ
- 목표: 람다와 LINQ를 활용해 데이터를 효율적으로 처리한다.
- 미션:
- 몬스터 리스트에서 체력이 가장 낮은 몬스터를 람다와 LINQ로 찾아라.
- 아이템 리스트에서 체력 회복 아이템만 추출하는 코드를 작성해라.
LINQ는 C#에서 지원하는 sql언어 같은 것이다.
컬렉션이나 json등 여러가지 데이터에서 사용하여 데이터를 가공할 수 있는 아주 편리한 기능이다.
사용법은 sql 처럼 where, orderby, select 등을 사용할 수도 있고, 함수를 사용할 수도 있다.
이번 미션에서는 함수로 사용했다.
// GameManager.cs
public List<Monster> monsters;
public List<Monster> FindHalfHpMonster()
{
return monsters?.Where(n => n.Hp < n.MaxHp / 2).ToList()?? new List<Monster>();
}
체력이 반 이하인 몬스터들만 필터링하여 리턴해주는 함수를 만들었다.
monsters뒤의 ? 은 nullable 이라는 키워드로 널이 들어오는 것이 가능하다는 의미이다. nullable 형식이 아니라면
null 일 때, 오류가 발생하게 된다.
그리고 Where 함수는 주어진 람다함수에 맞는 조건만 필터링해서 IEnumerable<Monster> 형태를 반환한다.
이것을 체이닝해서 .ToList로 리스트화 시킨 것이다.
?? 키워드는 왼쪽값이 널이면 오른쪽 값을 사용하라는 의미이다. 삼항연산자랑 비슷하다고 보면 된다.
LINQ 와 관련된 함수는 이외에 몇가지 소개하겠다.
var result = numbers.Where(n => n % 2 == 0); // 조건에 맞는 필터링
var squaredNumbers = numbers.Select(n => n * n); // 값 변환
var sorted = numbers.OrderBy(n => n); // 오름차순
var sortedDesc = numbers.OrderByDescending(n => n); // 내림차순
var firstEven = numbers.First(n => n % 2 == 0); // 조건에 맞는 요소 중 첫번째 반환
var firstOrDefaultEven = numbers.FirstOrDefault(n => n > 10); // 없으면 기본값 반환 (int는 0)
var grouped = numbers.GroupBy(n => n % 2 == 0 ? "짝수" : "홀수"); // 조건에 맞게 그룹화
var evenCount = numbers.Count(n => n % 2 == 0); // 개수
var sum = numbers.Sum(); // 합
var average = numbers.Average(); // 평균
var min = numbers.Min(); // 제일 작은거
var max = numbers.Max(); // 제일 큰거
bool hasEven = numbers.Any(n => n % 2 == 0); // 하나라도 만족하면 true
bool allEven = numbers.All(n => n % 2 == 0); // 모두 만족해야 true
var distinctNumbers = numbers.Distinct(); // 중복 제거
var firstThree = numbers.Take(3); // 처음 3개 가져오기
var skipTwo = numbers.Skip(2); // 처음 2개 건너뛰기
여기서 groupby는 요소를 그룹별로 나누는데 dictionary로 변환한다고 생각하면 쉽다. 또한 ToDictionary 함수도 지원된다.
또한 distinct 같은 경우는 Equals()와 GetHashCode() 함수의 재정의가 필요하다.
다음은 ItemManager에 필터링함수를 추가했다.
public List<T> FindItemByType<T>(ItemType type) where T : Item
{
if (Inventory.ContainsKey(type.ToString()) == false)
return new List<T>();
return Inventory[type.ToString()].OfType<T>().ToList();
}
원하는 아이템타입을 넘겨주면 해당 타입인 아이템을 필터링하여 그 타입으로 캐스팅 후, 리스트로 넘겨준다.
제너릭을 사용했고, where문으로 Item의 하위클래스만 T로 넘길 수 있게 하였다.
OfType또한 LINQ 함수인데, T에 해당하는 클래스만 골라서 캐스팅 후, 리턴값에 추가해준다.
이번미션은 꼭 텍스트 rpg에 필요해서 했다기보다는 LINQ문법을 사용해보는데 의미를 두었다.
'텍스트 Rpg - C#' 카테고리의 다른 글
C#으로 만드는 텍스트 Rpg (8) (0) | 2025.02.06 |
---|---|
C#으로 만드는 텍스트 Rpg (7) (0) | 2025.02.06 |
C#으로 만드는 텍스트 Rpg (5) (0) | 2025.02.05 |
C#으로 만드는 텍스트 Rpg (4) (0) | 2025.02.03 |
C#으로 만드는 텍스트 Rpg (3) (0) | 2025.02.01 |