언리얼 C++ 프로그래밍

[언리얼 C++] 컨테이너 클래스 TSet 사용법(쿼리, 엘리먼트 제거, 소팅)

언린이 2021. 7. 14. 22:46

TSet 컨테이너 클래스의 기본적인 설명과 간단한 사용법은 [언리얼 C++] 컨테이너 클래스 TSet 사용법(생성 및 삽입, 반복처리) (tistory.com) 글을 참고하시기 바랍니다.

이 글에서는 TSet 컨테이너 클래스의 쿼리, 엘리먼트 제거, 소팅 기능에 대해 알아보겠습니다.

 

 

1. TSet 컨테이너 쿼리 기능

int32 Count = FruitSet.Num(); // Count = 8

현재 TSet 컨테이너에 있는 엘리먼트 개수를 알아내려면 Num() 함수를 호출하면 됩니다.

 

bool bHasBanana = FruitSet.Contains(TEXT("Banana")); // bHasBanana = true
bool bHasLemon = FruitSet.Contains(TEXT("Lemon")); // bHasLemon = false

TSet 컨테이너에 지정한 엘리먼트가 존재하는지 확인하려면, Contains() 함수를 호출하면 됩니다.

 

FSetElementId BananaIndex = FruitSet.Index(TEXT("Banana"));
// BananaIndex is a value between 0 and (FruitSet.Num() - 1)
FPlatformMisc::LocalPrint(
    *FString::Printf(
        TEXT(" \"%s\"\n"),
        *FruitSet[BananaIndex]
    )
);
// Prints "Banana"

FSetElementId LemonIndex = FruitSet.Index(TEXT("Lemon"));
// LemonIndex is INDEX_NONE (-1)
FPlatformMisc::LocalPrint(
    *FString::Printf(
        TEXT(" \"%s\"\n"),
        *FruitSet[LemonIndex]
    )
); // Assert!

그리고 FSetElementId 구조체를 사용하여 TSet 컨테이너 내 Key 인덱스를 찾을 수 있습니다. 그리고 나서 operator[]로 해당 Key 인덱스를 사용하여 엘리먼트를 가져올 수 있습니다. const가 아닌 TSet 컨테이너에 operator[]를 호출하면 const가 아닌 레퍼런스가 반환되고, const TSet 컨테이너에서 호출하면 const 레퍼런스가 반환됩니다.

 

FString* PtrBanana = FruitSet.Find(TEXT("Banana")); // *PtrBanana = "Banana"
FString* PtrLemon = FruitSet.Find(TEXT("Lemon")); //  PtrLemon = nullptr

TSet 컨테이너에 Key가 있는지 확실하지 않은 경우, Contains() 함수, 그리고 operator[]를 사용하여 검사할 수 있지만 그리 이상적이지는 않습니다. 성공적으로 가져오기 위해서는 같은 Key에 조회를 두번해야 하기 때문입니다.

그래서 이를 위해서 TSet 컨테이너 클래스는 Find() 함수를 제공해줍니다. Find() 함수는 이 동작을 조회 단 한번으로 합칩니다. Find() 함수는 TSet 컨테이너에 Key가 있는 경우 엘리먼트로의 포인터를 반환하고, 없으면 널 포인터를 반환합니다. const TSet 컨테이너에 Find() 함수를 호출하면 반환되는 포인터도 const가 됩니다.

 

TArray<FString> FruitArray = FruitSet.Array();
// FruitArray = { "Banana","Grapefruit","Pineapple","Pear","Orange","Kiwi","Melon","Mango" }

마지막으로, Array() 함수를 사용하여 TSet 컨테이너의 모든 엘리먼트들의 사본으로 채워진 TArray 컨테이너를 생성할 수 있습니다. TArray 컨테이너를 먼저 비운 뒤 연산이 시작되므로, 최종 엘리먼트 수는 TSet 컨테이너의 엘리먼트 수와 항상 같을 것입니다.

 

 

2. TSet 컨테이너 엘리먼트 제거 기능

int32 RemovedAmountPineapple = FruitSet.Remove(TEXT("Pineapple")); // RemovedAmountPineapple = 1
// FruitSet = { "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" }

int32 RemovedAmountLemon = FruitSet.Remove(TEXT("Lemon")); // RemovedAmountLemon = 0

TSet 컨테이너의 엘리먼트 제거는 Remove() 함수에 파라미터로 Key를 넘겨 제거할 수 있습니다.

Remove() 함수는 제거된 엘리먼트 수를 반환하며, 제공된 Key가 TSet 컨테이너에 들어있지 않은 경우 0을 반환합니다.

TSet 컨테이너가 중복 Key를 지원하는 경우, 일치하는 모든 엘리먼트를 제거합니다.

 

TSet<FString> FruitSetCopy = FruitSet;
// FruitSetCopy = { "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" }

FruitSetCopy.Empty();
// FruitSetCopy = {}

마지막으로 Empty() 함수 또는 Reset() 함수로 모든 엘리먼트를 제거할 수 있습니다.

Empty() 함수와 Reset() 함수는 비슷하지만, Empty() 함수는 TSet 컨테이너에 남겨둘 슬랙 양을 지정할 수 있는 반면 Reset() 함수는 그럴 수 없습니다.

 

 

3. TSet 컨테이너 소팅 기능

FruitSet.Sort([](const FString& A, const FString& B) {
    return A > B; // sort by reverse-alphabetical order
});
// FruitSet = { "Pear", "Orange", "Melon", "Mango", "Kiwi", "Grapefruit" } (order is temporarily guaranteed)

FruitSet.Sort([](const FString& A, const FString& B) {
    return A.Len() < B.Len(); // sort strings by length, shortest to longest
});
// FruitSet = { "Pear", "Kiwi", "Melon", "Mango", "Orange", "Grapefruit" } (order is temporarily guaranteed)

TSet 컨테이너는 소팅이 가능합니다. 소팅 이후 TSet 컨테이너를 반복처리하면 소팅된 순서대로 나오긴 하지만, TSet 컨테이너가 변경되면 더이상 그 순서가 보장되지 않습니다. 소팅은 불안정하므로, 중복 Key를 허용하는 TSet 컨테이너의 엘리먼트는 순서 없이 나타날 수 있습니다.

위 예제 코드처럼 TSet 컨테이너 클래스의 Sort() 함수는 이항 술부를 파라미터로 받아 소팅 순서를 지정합니다.