- 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