1. Enumerable.Repeat()
C#으로 코드를 짜다보면 종종 어떤 하나의 객체를, 그 객체를 담고 있는 IEnumerable<T>
로 변환해야 하는일이 종종 생긴다. 그땐 Enumerable.Repeat()을 사용하면 편하다.
예를들어, 어떤 메소드 중간에 객체 obj
가 있고, 이것을 IEnumerable<>
타입으로 만들어서 반환해야 한다고 생각해보자.
GameObject obj;
가장 단순하게 생각해보자면, List<>
컨테이너를 하나 할당해서 그 리스트에 값을 집어넣을 수 있다.
List<GameObject> list = new List<GameObject>(1);
list.Add(obj);
return list;
유니티3d 엔진의 코루틴 기능을 알고 있다면, C#의 발생자 문법을 사용하는 방식도 생각해 볼 수 있겠다.
IEnumerable<GameObject> ToEnumerable(GameObject obj)
{
yield return obj;
yield break;
}
...
return ToEnumerable(obj);
하지만 대충봐도 알겠지만 귀찮다. 정말 귀찮다. 저 두 세줄 늘어나는게 정말 귀찮다. 특히 (디버깅도 귀찮게 잘 안되는) Linq로 길게 이어지는 람다 함수 체인들 속에서 저런 코드를 짜는건 매우 귀찮다. 게다가 리스트는 메모리도 더 먹겠지.
이럴땐 Enumerable.Repeat()
메소드를 사용해주면 된다.
return Enumerable.Repeat(obj, 1);
메소드 이름에서 유추할 수 있겠지만, obj
객체를 1번 반복해서 내 뱉는 IEnumerable<GameObject>
를 만들어낸다.
2. 최근에 써먹어본 곳
최근에 아이템 보상 정보들을 합칠 수 있는 타입이면 하나의 보상 정보로 합치고, 아니면 그냥 냅두는 루틴을 작성했어야 했다.
예를들면, [돈 10, 돈 20, 무기(칼), 무기(창)]의 보상 정보 리스트가 있을 때, 돈 타입의 보상 정보를 하나로 합쳐서 [돈 30, 무기(칼), 무기(창)]의 리스트로 만드는 루틴이라고 생각하면 된다.
보상 정보들을 GroupBy
로 묶고, 나온 IGrouping
들을 처리할 때 써먹었다.
/// <summary>
/// 아이템 타입에 따라 (가능하면) 수량을 합쳐서 돌려주는 메소드.
/// </summary>
public static IEnumerable<ItemInfo> CombineItemInfo(IEnumerable<ItemInfo> rewards)
{
IEnumerable<ItemInfo> combinedRewards = rewards
.GroupBy(reward => reward.subType)
.Select(group =>
{
ItemType itemType = group.FirstOrDefault().itemType; // hmmmm...
switch (itemType)
{
case ItemType.COLLAPSIBLE_TYPE0:
case ItemType.COLLAPSIBLE_TYPE1:
case ItemType.COLLAPSIBLE_TYPE2:
// Merge quantities
int quantity = group.Select(reward => reward.quantity).Sum();
return Enumerable.Repeat(new ItemInfo(itemType, group.Key, quantity), 1);
case ItemType.COLLAPSIBLE_TYPE3:
case ItemType.COLLAPSIBLE_TYPE4:
// Merge in other way..
break;
default:
// No need to be merged
return group;
}
})
.SelectMany(x => x); // flatMap
return combinedRewards;
}
대충 gist는 이러하다. 물론 당연히 원본 소스는 아님.
'프로그래밍' 카테고리의 다른 글
Roslyn으로 C# 코드 정적 분석하기 (0) | 2018.03.05 |
---|---|
라인하르트 방어막 셰이더 흉내내기 (0) | 2017.11.27 |
Using Linq in Unity3d (0) | 2017.10.29 |
쿼터니온(Quaternion) 정리 (5) | 2017.08.28 |
렌더링 파이프라인에서 왜 동차 좌표계를 쓸까 (3) | 2017.07.09 |