-
텍스트 던전 콘솔로 구현하기 - 작업중 학습(1)카테고리 없음 2023. 8. 22. 21:12
Case 1
: 아이템을 정렬할 때, 선택한 기준에 대해서 기준마다 내림차순, 오름차순, 원본의 순서대로 출력하려고 한다.
: 다음과 같은 코드를 계속 쓰면, 코드가 너무 지저분해지고, 반복적으로 되므로 수정하려고 함.
switch(selectIndex) { case 0: equipped = equipped.Replace(markArray[(clickCount - 1) % 3] + " |", markArray[clickCount % 3] + " |"); // 다른 이름으로 변경시, 초기화 해주는 기능 추가해야함. // 아이템 if (clickCount % 3 == 1) { var isEquippedList = from item in inventoryList orderby item.IsEquiped descending select item; inventoryList = isEquippedList.ToList<Item>(); inventory.GetThisListToInventory(inventoryList); } else if (clickCount % 3 == 2) { var isEquippedList = from item in inventoryList orderby item.IsEquiped select item; inventoryList = isEquippedList.ToList<Item>(); inventory.GetThisListToInventory(inventoryList); } else { inventory.GetThisListToInventory(originalList); inventoryList = originalList.ToList<Item>(); } break; //... 생략 ...
람다 (Lambda)
: 이름이 없는 메서드
: 참조만을 가지고 컨트롤.
: 델리게이트에 지정한다면, 이름이 없더라도 추후에 다시 부를 수 있다.
(파라미터 목록) => 표현식
: 특정 객체의 필드를 지정할 수도 있다.
item => item.IsEquiped
: 람다 자체가 메서드의 파라미터가 될 수도 있다.
List<Item> inventoryList0 = inventory.OrderInventoryByProperty(item => item.IsEquiped, descending);
Func
: 값을 반환하는 메서드를 나타내는 델리게이트
// 객체의 필드를 선택하는 메서드 static bool IsEquippedSelector(Item item) { return item.IsEquiped; } // Func를 사용하면.. item => item.isEquiped // 해당 Func를 다시 사용하려면.. Func<Item T> propertySelector
Action
: 값을 반환하지 않는 메서드를 나타내는 델리게이트
// Action을 사용하여 문자열을 출력하는 메서드 void PrintMessage(string message) { Console.WriteLine(message); } // Action을 이용한 메서드 호출 Action<string> printAction = PrintMessage; printAction("Hello, World!");
Linq (Language Integrated Query)
: .NET 프레임워크에서 제공되는 쿼리 언어 확장
: 데이터 소스(예: 컬렉션, 데이터베이스, XML 문서 등)에서 데이터를 쿼리하고 조작하는데 사용
List<T> 와 조합하여 다음과 같은 조합이 가능하다.
// 정렬 itemList.OrderByDescending("필드") // 필드의 값을 내림차순으로 정렬 itemList.OrderBy("필드") // 필드의 값을 오름차순으로 정렬 // 검색 itemList.Find("필드" + 조건 람다식) // 해당 필드에서 조건 람다식에 맞는 값 중 가장 처음의 요소를 검색 itemList.FindAll("필드" + 조건 람다식) // 해당 필드에서 조건 람다식에 맞는 모든 값을 검색 itemList.FindIndex("필드" + 조건 람다식) // 해당 필드에서 조건 람다식에 맞는 값 중 가장 처음 요소의 인덱스를 검색 itemList.Exists("필드" + 조건 람다식) // 해당 필드에서 조건 람다식에 맞는 값이 있는지 여부를 bool 로 반환 // 조건 itemList.Where("필드 + 조건 람다식) // 해당 필드에서 조건 람다식에 맞는 모든 값 반환
해결
: Linq 부분을 조건 람다식과 필드, 내장 함수의 조합으로 줄임.
// Before var isEquippedList = from item in inventoryList orderby item.IsEquiped descending select item; // after isEquippedList = inventoryList.OrderByDescending(item => item.IsEquiped);
: 이후, isEquippedList 를 inventoryList 에 복사함.
// Before var isEquippedList = from item in inventoryList orderby item.IsEquiped descending select item; inventoryList = isEquippedList.ToList(); // Mid isEquippedList = inventoryList.OrderByDescending(item => item.IsEquiped); inventoryList = isEquippedList.ToList(); // After inventoryList = inventoryList.OrderByDescending(item => item.IsEquiped).ToList();
: 원본의 스위치문은, 클릭횟수를 저장하는 정수 clickCount를 3으로 나눈 나머지를 기준으로 오름차순, 내림차순, 원본 순서를 정함.
//before if (clickCount % 3 == 1) { inventoryList = inventoryList.OrderByDescending(item => item.IsEquiped).ToList(); } else if (clickCount % 3 == 2) { inventoryList = inventoryList.OrderBy(item => item.IsEquiped).ToList(); } else { inventory.GetThisListToInventory(originalList); inventoryList = originalList.ToList<Item>(); } // After Class Inventory { //... 생략 ... public List<Item> ChangeOrder(List<Item> inventoryList, Func<Item, T> itemField, int clickCount) { if (clickCount % 3 == 1) { return inventoryList.OrderByDescending(itemField).ToList(); } else if (clickCount % 3 == 2) { return inventoryList.OrderBy(itemField).ToList(); } } //... 생략 ... } if (clickCount % 3 == 0) { inventory.GetThisListToInventory(originalList); inventoryList = originalList.ToList<Item>(); } else { inventoryList = inventory.ChangeOrder(inventoryList, item => item.IsEquiped, clickCount); }
최종 수정
if (clickCount % 3 == 0) { inventory.GetThisListToInventory(originalList); inventoryList = originalList.ToList<Item>(); } else { switch (selectIndex) { case 0: equipped = equipped.Replace(markArray[(clickCount - 1) % 3] + " |", markArray[clickCount % 3] + " |"); // 다른 이름으로 변경시, 초기화 해주는 기능 추가해야함. inventoryList = inventory.ChangeOrder(inventoryList, item => item.IsEquiped, clickCount); // 아이템 break; case 1: arrangeName = arrangeName.Replace(markArray[(clickCount - 1) % 3] + " |", markArray[clickCount % 3] + " |"); inventoryList = inventory.ChangeOrder(inventoryList, item => item.ItemName, clickCount); break; case 2: inventoryList = inventory.ChangeOrder(inventoryList, item => item.Atk, clickCount); attackName = attackName.Replace(markArray[(clickCount - 1) % 3] + " |", markArray[clickCount % 3] + " |"); break; case 3: defendName = defendName.Replace(markArray[(clickCount - 1) % 3] + " |", markArray[clickCount % 3] + " |"); inventoryList = inventory.ChangeOrder(inventoryList, item => item.Def, clickCount); break; default: break; } }