LINQ란?
– LINQ(Language Integrated Query)는 .NET 언어(C#, VB.NET 등)에서 데이터를 쿼리하고
조작하기 위한 강력한 기능을 제공하고 있다.
– LINQ를 사용하면 SQL 데이터베이스, XML 문서, 배열 및 컬렉션과 같은 다양한 데이터 소스에
대해 일관된 구문을 사용하여 데이터 접근이 훨씬 간결하고 직관적으로 보인다.
- LINQ를 Unity에서 접목 시키면 좋은 점.
- 데이터 관리가 간편해진다. 더 쉽게 검색하고, 필터링 할 수 있으며, 정렬 할 수 있다.
- 코드의 가독성과 유지 보수에 좋다.
√ LINQ의 주요 기능 사용 예제(Where, Select, OrderBy, FirstOrDefault)
01. Where
where을 사용하면 원본 배열에서 특정 조건을 만족하는 요소들을 필터링 할 때 사용된다.
using System.Linq;
using UnityEngine;
public class EnemyManager : MonoBehaviour {
public GameObject[] enemies;
void Start() {
//게임오브젝트의 position.x > 100f 보다 큰 게임오브젝트를 찾아서 리스트 생성.
var result = enemies.Where(enemy => enemy.transform.position.x > 100f);
}
}
요약
Where는 필터링 작업에 유용하다. 특정 조건에 해당하는 데이터들로 새로운 배열을 생성할 수 있으며, 데이터 처리와 검색 작업을 간단하고 효율적으로 처리 할 수 있다.
02. Select
select는 해당 리스트의 데이터를 변형하여 다른 형태의 데이터로 반환할 때 사용된다.
예를 들어 데이터의 특정 속성만 추출하거나, 데이터를 다른 형태로 매핑할 때 유용하다.
게임 오브젝트의 이름 목록을 얻거나, 게임 오브젝트의 위치 값들로 생성할 수 있다.
using System.Linq;
using UnityEngine;
public class EnemyManager : MonoBehaviour {
public GameObject[] enemies;
void Start() {
//게임오브젝트 배열의 name들로 리스트 생성.
var result = enemies.Select(enemy => enemy.name);
}
}
요약
Select는 배열 요소를 다양한 형태로 변환 할 수 있으며, 데이터 처리와 가공에 매우 유용하다.
03. OrderBy 및 OrderByDescending
OrderBy와 OrderByDescending는 해당 리스트를 정렬하는데 사용된다.
특정 속성을 기준으로 오름차순, 내림차순 정렬을 할 수 있다.
using System.Linq;
using UnityEngine;
public class EnemyManager : MonoBehaviour {
public GameObject[] enemies;
void Start() {
//enemy의 hp를 기준으로 오름차순 정렬.
var hpList = enemies.OrderBy(enemy => enemy.hp);
//enemy의 mp를 기준으로 내림차순 정렬.
var mpList = enemies.OrderByDescending(enemy => enemy.mp);
}
}
요약
Unity에서 게임 데이터를 다룰 때, 정렬 기능을 사용하면 데이터를 효율적으로 정렬하고 관리할 수 있다.
특히 점수판, 리더보드, 인벤토리 아이템 정렬 등 다양한 상황에서 활용할 수 있다.
04. FirstOrDefault
FirstOrDefault는 조건을 만족하는 첫 번째 요소를 검색하는 데 사용된다.
만약 조건을 만족하는 요소가 없다면, 참조 타입의 경우 null, 값 타입의 경우 기본 값 0이 반환 된다.
using System.Linq;
using UnityEngine;
public class EnemyManager : MonoBehaviour {
public GameObject[] enemies;
void Start() {
//게임오브젝트 배열에서 이름이 "EnemyBoss"인 첫 번째 오브젝트를 찾아서 반환.
var boss = enemies.FirstOrDefault(enemy => enemy.name == "EnemyBoss");
if (enemy != null) {
//이름이 "EnemyBoss" 오브젝트를 찾음.
}
else {
//이름이 "EnemyBoss" 오브젝트를 못 찾음.
}
}
}
요약
Unity에서 게임 데이터를 다룰 때, FirstOrDefault를 사용하면 조건에 만족하는 첫번째 데이터를 빠르게 찾을 수 있다. 만약 조건에 만족하는 데이터가 없을 때도 예외 처리를 간단히 할 수 있는 장점도 있다.
LINQ 메서드를 복합적으로 사용하면 더욱 강력하고 간결한 코드를 작성할 수 있다.
예를 들어, Where와 Select를 조합하여 특정 조건을 만족하는 요소를 필터링하고,
그 요소의 특정 속성을 추출하는 작업을 한 줄의 코드로 처리할 수 있다.
여기에 FirstOrDefault까지 포함하여 복합적으로 사용 가능 하다.
using System.Linq;
using UnityEngine;
public class GameManager : MonoBehaviour {
public GameObject[] gameObjects;
void Start() {
//활성화된 게임오브젝트 중 첫 번째 오브젝트의 이름 추출
var name = gameObjects.Where(obj => obj.activeSelf)
.Select(obj => obj.name)
.FirstOrDefault();
if (name != null) {
//활성화 중인 첫번째 게임오브젝트 이름 확인 o
}
else {
//활성화 중인 첫번째 게임오브젝트 이름 확인 x
}
}
}
하지만 사용에 있어서 주의할 점도 있다.
LINQ를 사용하면 코드를 간결하고 가독성 있게 작성할 수 있지만, 내부적으로는 다양한 데이터 구조를 순회하고 변환하기 때문에 성능 면에서 비용이 발생할 수 있다.
특히, LINQ로 쿼리를 작성하면 호출이 많이 발생하여 박싱 및 가비지 생성이 증가할 수 있기 때문에 사용에 있어서 주의 해야 한다.
성능이 중요한 경우 LINQ를 사용하지 않고, 대신 for 루프와 리스트를 사용하는 것이 좋다.
메모리 할당과 가비지 생성을 최소화하여 성능을 향상시킬 수 있기 때문이다.
using System.Linq;
using UnityEngine;
public class GameManager : MonoBehaviour {
public GameObject[] gameObjects;
void Start() {
string[] strings = { "apple", "banana", "cherry", "date", "elderberry" };
//1. LINQ와 정규식을 사용하여 'e'가 포함된 단어를 찾고 대문자로 변환하는 예시.
var result = strings
.Where(s => Regex.IsMatch(s, "e"))
.Select(s => s.ToUpper())
.ToArray();
//2. for 루프와 리스트를 사용하여 'e'가 포함된 단어를 찾고 대문자로 변환하는 예시.
List<string> resultList = new List<string>();
foreach (var s in strings) {
if (s.Contains("e")) {
resultList.Add(s.ToUpper());
}
}
}
}
따라서, 상황에 맞게 두 접근 방식을 균형 있게 사용하는 것이 좋다.
– 성능이 중요한 부분에서는 for문
– 가독성과 유지보수성이 중요한 부분에서는 LINQ
- 성능 요구 사항: 성능이 중요한 경우(특히 실시간 시스템이나 게임 개발에서), for문 사용.
- 코드 가독성 및 유지보수성: 코드의 가독성과 유지보수성이 중요한 경우 LINQ를 사용.
- 작업 복잡도: 복잡한 데이터 쿼리와 변환 작업이 필요한 경우 LINQ가 더 적합할 수 있다.
하지만, 단순한 반복 작업은 for문으로도 충분 하다.