1. 링크(LINQ, Language-Integrated Query)
링크(LINQ, Language-Integrated Query)는 C# 언어에서 쿼리 기능을 사용하는 것입니다.
여기서 쿼리란 데이터를 조회, 질의 하고, 조건에 맞는 데이터를 추출, 조작하는 명령어입니다.
표준 쿼리 연산자는 LINQ 패턴을 형성하는 메서드입니다.
이 메서드 중 대부분은 시퀀스에서 작동합니다.
여기서 시퀀스란 IEnumerable 인터페이스 또는 IQueryable 인터페이스를 구현하는 형식의 객체를 의미합니다.
네임스페이스 |
using System.Linq; |
2. 데이터 정렬
정렬 작업은 하나 이상의 특성을 기준으로 시퀀스 요소를 정렬하는 작업입니다.
메서드 이름 |
설명 |
C# 쿼리 식 구문 |
OrderBy |
값을 오름차순으로 정렬합니다. |
orderby |
OrderByDescending |
값을 내림차순으로 정렬합니다. |
orderby … descending |
ThenBy |
2차 정렬을 오름차순으로 수행합니다. |
orderby …, … |
ThenByDescending |
2차 정렬을 내림차순으로 수행합니다. |
orderby …, … descending |
Reverse |
컬렉션에서 요소의 순서를 반대로 바꿉니다. |
|
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class LinqSortingDataExample : MonoBehaviour
{
void Start()
{
string[] avengers = { "Iron Man", "Captain America", "Thor", "Hulk", "Black Panther", "Spider Man" };
// OrderBy
IEnumerable<string> query = from hero in avengers
orderby hero.Length
select hero;
foreach (string str in query)
Debug.Log(str); // 출력 : Thor Hulk Iron Man Spider Man Black Panther Captain America
// OrderByDescending
query = from hero in avengers
orderby hero.Substring(0, 1) descending
select hero;
foreach (string str in query)
Debug.Log(str); // 출력 : Thor Spider Man Iron Man Hulk Captain America Black Panther
query = from hero in avengers
orderby hero.Length, hero.Substring(0, 1)
select hero;
foreach (string str in query)
Debug.Log(str); // 출력 : Hulk Thor Iron Man Spider Man Black Panther Captain America
query = from hero in avengers
orderby hero.Length, hero.Substring(0, 1) descending
select hero;
foreach (string str in query)
Debug.Log(str); // 출력 : Thor Hulk Iron Man Spider Man Black Panther Captain America
}
}
3. 집합 작업
집합 작업은 동일 컬렉션이나 별개 컬렉션(또는 집합)에 동등한 요소가 있는지 여부에 따라 결과 집합을 생성하는 쿼리 작업입니다.
메서드 이름 |
설명 |
Distinct |
컬렉션에서 중복 값을 제거합니다. |
Except |
두 번째 컬렉션에 표시되지 않는 한 컬렉션의 요소를 의미하는 차집합을 반환합니다. |
Intersect |
두 컬렉션에 각각 표시되는 요소를 의미하는 교집합을 반환합니다. |
Union |
두 컬렉션 중 하나에 표시되는 고유한 요소를 의미하는 합집합을 반환합니다. |
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class LinqSetOperationsExample : MonoBehaviour
{
void Start()
{
// Distinct
string[] avengers1 = { "Iron Man", "Iron Man", "Captain America", "Thor" };
IEnumerable<string> query = from hero in avengers1.Distinct()
select hero;
foreach (var str in query)
{
Debug.Log((str)); // 출력 : Iron Man Captain America Thor
}
// Except
string[] avengers21 = { "Iron Man", "Captain America", "Thor" };
string[] avengers22 = { "Iron Man", "Hulk", "Captain America" };
query = from hero in avengers21.Except(avengers22)
select hero;
foreach (var str in query)
{
Debug.Log((str)); // 출력 : Thor
}
// Intersect
query = from hero in avengers21.Intersect(avengers22)
select hero;
foreach (var str in query)
{
Debug.Log((str)); // 출력 : Captain America
}
// Union
query = from hero in avengers21.Union(avengers22)
select hero;
foreach (var str in query)
{
Debug.Log((str)); // 출력 : Iron Man, Captain America Thor Hulk
}
}
}
4. 데이터 필터링
데이터 필터링은 지정된 조건을 충족하는 요소만 포함하도록 결과 집합을 제한하는 작업입니다.
메서드 이름 |
설명 |
C# 쿼리 식 구문 |
OfType |
지정된 형식으로 캐스트할 수 있는지 여부에 따라 값을 선택합니다. |
|
Where |
조건자 함수를 기반으로 하는 값을 선택합니다. |
where |
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class LinqFilteringDataExample : MonoBehaviour
{
void Start()
{
string[] avengers = { "Iron Man", "Captain America", "Thor", "Hulk", "Black Panther", "Spider Man" };
IEnumerable<string> query = from hero in avengers
where hero.Length == 4
select hero;
foreach (string str in query)
Debug.Log(str); // 출력 : Thor Hulk
}
}
5. 수량자 작업
수량자 작업은 시퀀스에서 조건을 충족하는 요소가 일부인지 전체인지를 나타내는 것을 참/거짓으로 반환합니다.
메서드 이름 |
설명 |
All |
시퀀스의 모든 요소가 조건을 만족하는지를 확인합니다. |
Any |
시퀀스의 임의의 요소가 조건을 만족하는지를 확인합니다. |
Contains |
시퀀스에 지정된 요소가 들어 있는지를 확인합니다. |
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
class Avengers
{
public string Name { get; set; }
public string[] Weapon { get; set; }
}
public class LinqQuantifierOperationsExample : MonoBehaviour
{
List<Avengers> avengers = new List<Avengers>
{
new Avengers { Name = "Iron Man", Weapon = new string[] { "Mk.01", "Mk.44", "Mk.85" } },
new Avengers { Name = "Thor", Weapon = new string[] { "Mjolnir", "Storm Breaker" } },
new Avengers { Name = "Captain America", Weapon = new string[] { "Mjolnir", "Shield" } },
};
void Start()
{
// All
IEnumerable<string> names = from hero in avengers
where hero.Weapon.All(item => item.Length == 5)
select hero.Name;
foreach (string name in names)
{
Debug.Log(name); // 출력 : Iron Man
}
// Any
names = from hero in avengers
where hero.Weapon.Any(item => item.StartsWith("M"))
select hero.Name;
foreach (string name in names)
{
Debug.Log(name); // 출력 : Iron Man Thor Captain America
}
// Contains
names = from hero in avengers
where hero.Weapon.Contains("Mjolnir")
select hero.Name;
foreach (string name in names)
{
Debug.Log(name); // 출력 : Thor Captain America
}
}
}
6. 프로젝션 작업
프로젝션은 주로 이후에 사용할 속성으로만 구성된 새 양식으로 개체를 변환하는 작업입니다.
메서드 이름 |
설명 |
C# 쿼리 식 구문 |
Select |
변환 함수를 기반으로 하는 값을 프로젝션합니다. |
select |
SelectMany |
변환 함수를 기반으로 하는 값의 시퀀스를 프로젝션한 다음 하나의 시퀀스로 평면화합니다. |
여러 from 절 사용 |
using UnityEngine;
using System.Linq;
public class LinqProjectionOperationsExample : MonoBehaviour
{
void Start()
{
string[] avengers = { "Iron Man", "Captain America", "Thor" };
var query = from hero in avengers
select hero.Substring(0, 1);
foreach (string s in query)
Debug.Log(s); // 출력 : I C T
}
}
7. 데이터 분할
LINQ의 분할은 요소를 다시 정렬한 후 섹션 중 하나를 반환하지 않고 입력 시퀀스를 두 개의 섹션으로 나누는 작업입니다.
연산자 이름 |
설명 |
Skip |
시퀀스에서 지정한 위치까지 요소를 건너뜁니다. |
SkipWhile |
요소가 조건을 충족하지 않을 때까지 조건자 함수를 기반으로 하여 요소를 건너뜁니다. |
Take |
시퀀스에서 지정된 위치까지 요소를 사용합니다. |
TakeWhile |
요소가 조건을 충족하지 않을 때까지 조건자 함수를 기반으로 하여 요소를 사용합니다. |
8. 조인 작업
두 데이터 소스를 조인하는 것은 한 데이터 소스의 개체를 공통 특성을 공유하는 다른 데이터 소스의 개체와 연결하는 작업입니다.
메서드 이름 |
설명 |
C# 쿼리 식 구문 |
Join |
키 선택기 함수를 기준으로 두 시퀀스를 조인한 다음 값 쌍을 추출합니다. |
join … in … on … equals … |
GroupJoin |
키 선택기 함수를 기준으로 두 시퀀스를 조인한 다음 결과로 생성된 일치 항목을 요소마다 그룹화합니다. |
join … in … on … equals … into … |
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
class Avengers
{
public string Name { get; set; }
public int CategoryId { get; set; }
}
class Category
{
public int Id { get; set; }
public string CategoryName { get; set; }
}
public class LinqJoinOperationsExample : MonoBehaviour
{
List<Avengers> avengers = new List<Avengers>
{
new Avengers { Name = "Iron Man", CategoryId = 0 },
new Avengers { Name = "Captain America", CategoryId = 0 },
new Avengers { Name = "Thor", CategoryId = 1 },
new Avengers { Name = "Loki", CategoryId = 1 }
};
List<Category> categories = new List<Category>
{
new Category { Id = 0, CategoryName = "Human" },
new Category { Id = 1, CategoryName = "Not Human" },
};
void Start()
{
var avengerGroups = from category in categories
join avenger in avengers on category.Id equals avenger.CategoryId into avengerGroup
select avengerGroup;
foreach (var avengerGroup in avengerGroups)
{
Debug.Log("Group");
foreach (Avengers avenger in avengerGroup)
{
Debug.Log($"{avenger.Name,20}"); // 출력 : Iron Man Captain America Thor Loki
}
}
}
}
9. 데이터 그룹화
그룹화는 데이터를 그룹에 넣어 각 그룹의 요소가 공통 특성을 공유하게 하는 작업입니다.
메서드 이름 |
설명 |
C# 쿼리 식 구문 |
GroupBy |
공통 특성을 공유하는 요소를 그룹화합니다. 각 그룹은 IGrouping<TKey,TElement> 개체로 표시됩니다. |
group … by |
ToLookup |
키 선택기 함수에 따라 Lookup<TKey,TElement>(일대다 사전)에 요소를 삽입합니다. |
|
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class LinqGroupingDataExample : MonoBehaviour
{
void Start()
{
List<int> numbers = new List<int>() { 3, 2, 4, 66, 13 };
IEnumerable<IGrouping<int, int>> query = from number in numbers
group number by number % 2;
foreach (var group in query)
{
Debug.Log(group.Key == 0 ? "Even numbers:" : "Odd numbers:");
foreach (int i in group)
Debug.Log(i); // 출력 : Odd numbers: 3 13 Even numbers: 2 4 66
}
}
}
10. 생성 작업
생성은 값의 새 시퀀스를 만드는 작업을 나타냅니다.
메서드 이름 |
설명 |
DefaultIfEmpty |
빈 컬렉션을 기본값을 갖는 singleton 컬렉션으로 바꿉니다. |
Empty |
비어 있는 컬렉션을 반환합니다. |
Range |
일련의 숫자를 포함하는 컬렉션을 생성합니다. |
Repeat |
반복되는 값이 하나 들어 있는 컬렉션을 생성합니다. |
11. 같음 연산
해당 요소가 동일하고 같은 수의 요소를 포함 하는 두 시퀀스는 같은 것으로 간주됩니다.
메서드 이름 |
설명 |
SequenceEqual |
쌍 단위 방식으로 요소를 비교하여 두 시퀀스가 서로 같은지 확인합니다. |
12. 요소 작업
요소 작업은 시퀀스에서 특정 단일 요소를 반환합니다.
메서드 이름 |
설명 |
ElementAt |
컬렉션의 지정된 인덱스에 있는 요소를 반환합니다. |
ElementAtOrDefault |
컬렉션의 지정된 인덱스에 있는 요소를 반환하거나 인덱스가 범위를 벗어나면 기본값을 반환합니다. |
First |
컬렉션의 첫 번째 요소 또는 특정 조건에 맞는 첫 번째 요소를 반환합니다. |
FirstOrDefault |
컬렉션의 첫 번째 요소 또는 특정 조건에 맞는 첫 번째 요소를 반환합니다. 이러한 요소가 없으면 기본값을 반환합니다. |
Last |
컬렉션의 마지막 요소 또는 특정 조건에 맞는 마지막 요소를 반환합니다. |
LastOrDefault |
컬렉션의 마지막 요소 또는 특정 조건에 맞는 마지막 요소를 반환합니다. 이러한 요소가 없으면 기본값을 반환합니다. |
Single |
컬렉션의 유일한 요소 또는 특정 조건에 맞는 유일한 요소를 반환합니다. 반환할 요소가 없거나 두 개 이상 있는 경우 InvalidOperationException을 throw합니다. |
SingleOrDefault |
컬렉션의 유일한 요소 또는 특정 조건에 맞는 유일한 요소를 반환합니다. 반환할 요소가 없는 경우 기본값을 반환합니다. 반환할 요소가 두 개 이상 있는 경우 InvalidOperationException을 throw합니다. |
13. 데이터 형식 변환
변환 메서드는 입력 개체의 형식을 변경합니다.
메서드 이름 |
설명 |
C# 쿼리 식 구문 |
AsEnumerable |
IEnumerable<T>로 형식화된 입력을 반환합니다. |
|
AsQueryable |
(제네릭) IEnumerable을 (제네릭) IQueryable로 변환합니다. |
|
Cast |
컬렉션의 요소를 지정된 형식으로 캐스트합니다. |
명시적 형식 범위 변수를 사용합니다. |
OfType |
지정된 형식으로 캐스트할 수 있는지 여부에 따라 값을 필터링합니다. |
|
ToArray |
컬렉션을 배열로 변환합니다. 이 메서드는 쿼리를 강제로 실행합니다. |
|
ToDictionary |
키 선택기 함수에 따라 Dictionary<TKey,TValue>에 요소를 배치합니다. 이 메서드는 쿼리를 강제로 실행합니다. |
|
ToList |
컬렉션을 List<T>로 변환합니다. 이 메서드는 쿼리를 강제로 실행합니다. |
|
ToLookup |
키 선택기 함수에 따라 Lookup<TKey,TElement>(일 대 다 사전)에 요소를 배치합니다. 이 메서드는 쿼리를 강제로 실행합니다. |
|
using UnityEngine;
using System.Linq;
class Marvel
{
public string Name { get; set; }
}
class MarvelPsychic : Marvel
{
public string HeroType { get; set; }
}
public class LinqConvertingDataTypesExample : MonoBehaviour
{
void Start()
{
Marvel[] marvels = new Marvel[] {
new MarvelPsychic { Name = "Iron Man", HeroType = "Suit Hero" },
new MarvelPsychic { Name = "Spider Man", HeroType = "Suit Hero" },
new MarvelPsychic { Name = "Thor", HeroType = "God" },
new MarvelPsychic { Name = "Thanos", HeroType = "Villain" } };
var query = from MarvelPsychic marvelPsychic in marvels
where marvelPsychic.HeroType == "Suit Hero"
select marvelPsychic;
foreach (Marvel marvel in query)
Debug.Log(marvel.Name); // 출력 : Iron Man Spider Man
}
}
14. 연결 작업
연결은 한 시퀀스를 다른 시퀀스에 추가하는 작업을 나타냅니다.
메서드 이름 |
설명 |
C# 쿼리 식 구문 |
Concat |
두 시퀀스를 연결하여 하나의 시퀀스를 구성합니다. |
해당 사항 없음. |
15. 집계 작업
집계 작업에서는 값의 컬렉션에서 하나의 값을 계산합니다.
메서드 이름 |
설명 |
Aggregate |
컬렉션 값에 대해 사용자 지정 집계 작업을 수행합니다. |
Average |
값 컬렉션의 평균 값을 계산합니다. |
Count |
컬렉션에서 요소(선택적으로 조건자 함수를 충족하는 요소만) 개수를 계산합니다. |
LongCount |
큰 컬렉션에서 요소(선택적으로 조건자 함수를 충족하는 요소만) 개수를 계산합니다. |
Max |
컬렉션의 최대값을 확인합니다. |
Min |
컬렉션의 최소값을 확인합니다. |
Sum |
컬렉션에 있는 값의 합계를 계산합니다. |
'프로그램 > 유니티 C# 강좌' 카테고리의 다른 글
[유니티 C# 강좌] 24. 파일 입출력 (0) | 2021.06.22 |
---|---|
[유니티 C# 강좌] 23. 멀티스레드(Multi-thread) (0) | 2021.05.05 |
[유니티 C# 강좌] 21. 제네릭 컬렉션(General Collection) (1) | 2020.02.09 |
[유니티 C# 강좌] 20. 병렬 프로그래밍 (Parallel Programming) (0) | 2020.02.09 |
[유니티 C# 강좌] 19. 비동기 프로그래밍(Asynchronous Programming) (0) | 2020.02.06 |