UE4-容器-數據結構-TArray


  • UE4-容器-數據結構-TArray
  • Time: 2020年10月13日16:31:22
  • author: Yblackd


1. 創建

// 創建空數組,保存整數序列
TArray<int32> IntArray;
TArray<FString> StrArr;

2. 填充數據

2.1 增-Init

​ 使用Init函數,用大量元素副本填入TArray。

IntArray.Init(10, 5);
// IntArray == [10, 10, 10, 10, 10]		向IntArray中填充5個10

2.2 增-Add和Emplace

​ Add和Emplace最終效果一樣,存在細微不同

StrArr.Add("Hello");
StrArr.Emplace("World");
// StrArr == ["Hello", "World"]
  • Add將 創建一個臨時 FString,然后將臨時內容移至容器內的 新FString中
  • Emplace 將會直接創建 FString
  • 注意: 雖然最終結果一樣,但Emplace可便面創建不必要的 臨時變量,效率比Add高; 但是Add可讀性強,所以在淺顯類型上使用Add,在其他類型上使用Emplace

2.3 增-Append

​ 使用 Append 可以將一個 容器( TArray常規數據 )逐個添加到另一個容器中

FString Arr[] = {TEXT("Yang"), TEXT("Dong")};
StrArr.Append(Arr, ARRAY_COUNT(Arr));	// 注意,第二個參數:數組的長度
// StrArr == ["Hello", "World", "Yang", "Dong"]

2.4 增-AddUnique

​ 添加一個TArray中不存在的元素,如果已經存在則不添加。 使用運算符 == 判斷是否相等。

StrArr.AddUnique(TEXT("你好,楊東"));
// StrArr == ["Hello", "World", "Yang", "Dong", "你好,楊東"]

StrArr.AddUnique(TEXT("Hello"));
// StrArr is unchanged as "Hello" is already an element

2.5 增-Insert

​ 在指定位置 插入元素

StrArr.Insert(TEXT("Insert"), 1)
// StrArr == ["Hello", "Insert", World", "Yang", "Dong", "你好,楊東"] 

2.6 增-SetNum

​ 設置TArray元素數量,如果大於當前數量,則使用元素類型的默認構造函數創建新元素,如果數量小於當前數量,則將移除多余的元素。

StrArr.SetNum(8);
// StrArr == ["Hello", "Insert", World", "Yang", "Dong", "你好,楊東", "", ""]

StrArr.SetNum(5);
// StrArr == ["Hello", "Insert", World", "Yang", "Dong"] 

3. 遍歷

​ 多種方法,推介使用C++的 range-for; 下面3中遍歷方法 結果相同。

3.1 range-for

FString JoinedStr;
for (auto& Str : StrArr)
{
    JoinedStr += Str;
    JoinedStr += TEXT(" ");
}

// 將元組 StrArr 遍歷, 將遍歷結果 拼接字符串,字符串之間用 空格 隔開

3.2 基於索引的for循環

for (int32 Index = 0; Index != StrArr.Num(); ++Index)
{
    JoinedStr += StrArr[Index];
    JoinedStr += TEXT(" ");
}
StrArr == "Hello Insert World Yang Dong"

3.3 迭代器(CreateIterator 和 CreateConstIterator)

for (auto TempStrPtr = StrArr.CreateIterator(); TempStrPtr; ++TempStrPtr)
{
    JoinedStr += *StrArr;
    JoinedStr += TEXT(" ");
}

4. 排序

4.1 Sort

StrArr.Sort();
// StrArr == ["Dong", "Hello", Insert", "World", "Yang"] 
  • 自定義排序規則(Lambad 表達式)
StrArr.Sort(
    [](const FString& A, const FString& B)
    {return A.Len() < B.Len();}
);

// StrArr == ["Yang", "Dong", "Hello", "World", "Insert"] 
// 此時是按字符串長度進行排序。注意:等值元素(“Yang”和"Dong"、“Hello”和“World” 的長度相同)的相對排序無法保證。

4.2 HeapSort

​ HeapSort,堆排序。是否使用 HeapSort 取決於特定數據以及與 Sort 相比排序的效率。與 Sort 一樣,HeapSort 也無法保證等值元素的相對排序。

4.3 StableSort

​ 與 SortHeapSort 相比,StableSort 可以保證等值元素的相對排序。StableSort 會保持等值元素之前的順序。

5. 查詢

5.1 TArray 長度-Num

int32 Count = StrArr.Num();
// Count == 5

5.2 訪問元素-GetData

GetData函數獲取StrArr的指針,通過索引訪問TArray中的元素,如同普通的數組。如果容器為常量,則返回的指針也是常量。

FString* StrPtr = StrArr.GetData();
/*
StrArr == ["Hello", "Insert", World", "Yang", "Dong"] 
StrPtr[0] == "Hello"
StrPtr[1] == "Insert"
StrPtr[2] == "World"
StrPtr[3] == "Yang"
StrPtr[4] == "Dong"
StrPtr[5] - undefined behavior
*/

5.3 訪問元素-索引

FString Elem0 = StrArr[0];
// Elem0 == "Hello"

5.4 訪問元素-校驗索引

索引 小於0或大於等於TArray長度時, 為無效索引,會引起運行錯誤。使用IsValidIndex函數 校驗索引是否有效

bool bValidM1 = StrArr.IsValidIndex(-1);
bool bValid0 = StrArr.IsValidIndex(0);
bool bValid6 = StrArr.IsValidIndex(6);
/*
bValidM1 == false;
bValid0 == true;
bValid6 == false;
*/

5.5 訪問元素-反向索引

​ 使用Last函數從TArray末端反向索引

  • StrArr.Last() == StrArr.Last(0) == StrArr.Top()
FString Elem0 = StrArr.Last();
FString Elem1 = StrArr.Last(0);
FString Elem2 = StrArr.Last(1);
FString Elem3 = StrArr.Top();

// Elem0 == "Dong"
// Elem1 == "Dong"
// Elem2 == "Yang"
// Elem0 == "Dong"

5.6 訪問元素-Contains

​ 判斷TArray是否包含某個特定元素,使用 Contains

bool bHello = StrArr.Contains(TEXT("Hello"));
bool bNoExist = StrArr.Contains(TEXT("NoExist"));
/*
bHello == true;
bNoExist == false;
*/
  • 使用Lambda表達式判斷是否包含 具有指定特征 的元素,使用ContainsByPredicate
bool bLen5 = StrArr.ContainsByPredicate([](const FString& Str) {
    return Str.Len() == 5;
});

bool bLen6 = StrArr.ContainsByPredicate([](const FString& Str) {
    return Str.Len() == 6;
});
// bLen5 == true
// bLen6 == false

5.7 訪問元素-Find

​ 使用 Find 查找某個元素是否存在並返回其索引:

FindFindLast 會返回找到的 第一個 元素的索引,若未找到則返回 INDEX_NONE,FindLast從后往前查找。

int Index = StrArr.Find(TEXT("Hello"));
int IndexLast = StrArr.FindLast(TEXT("Hello"));
int IndexNone = StrArr.Find(TEXT("NONE"));
// Index2     == 0
// IndexLast2 == 0
// IndexNone  == INDEX_NONE

6. 刪除

6.1 Remove

Remove 會移除與傳入元素相等的 所有 元素, RemoveSingle 則只會移除TArray中與傳入元素相等的最靠前的一個元素。

// 刪除前:StrArr == ["Hello", "Insert", World", "Yang", "Dong"] 
StrArr.Remove(TEXT("Hello"));
StrArr == ["Insert", "World", "Yang", "Dong"] 
StrArr.Remove(TEXT("goodbye"));
// StrArr is unchanged, as it doesn't contain "goodbye"

6.2 RemoveAt

RemoveAt 按元素索引移除元素。索引必須存在,否則會出現運行時錯誤。還可以使用 RemoveAllLambda表達式 的方式來移除具有某些特征的所有元素。

StrArr.RemoveAt(1);

/*
刪除前
StrArr == ["Hello", "Insert", World", "Yang", "Dong"] 

刪除后
StrArr == ["Hello", “World", "Yang", "Dong"] 
*/

6.2 Pop

Pop 將移除TArray的最后一個元素:

StrArr.Pop();
// StrArr == ["!","Brave","World"]

​ 以上這些情況,當元素被移除時,其后的元素會向前移,移動過程存在開銷。若不介意剩余元素的排序,可使用 RemoveSwapRemoveAtSwapRemoveAllSwap 來減少開銷。使用 Empty 可以移除所有的元素。


7. 參考

參考鏈接:https://blog.csdn.net/u011476173/article/details/98619270?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM