- 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
與 Sort 和 HeapSort 相比,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 查找某個元素是否存在並返回其索引:
Find 和 FindLast 會返回找到的 第一個 元素的索引,若未找到則返回 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 按元素索引移除元素。索引必須存在,否則會出現運行時錯誤。還可以使用 RemoveAll 以 Lambda表達式 的方式來移除具有某些特征的所有元素。
StrArr.RemoveAt(1);
/*
刪除前
StrArr == ["Hello", "Insert", World", "Yang", "Dong"]
刪除后
StrArr == ["Hello", “World", "Yang", "Dong"]
*/
6.2 Pop
Pop 將移除TArray的最后一個元素:
StrArr.Pop();
// StrArr == ["!","Brave","World"]
以上這些情況,當元素被移除時,其后的元素會向前移,移動過程存在開銷。若不介意剩余元素的排序,可使用 RemoveSwap、RemoveAtSwap 和 RemoveAllSwap 來減少開銷。使用 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