TArray是存储相同类型数据的动态数组,具有速度快,内存消耗小,安全性高的特点。
使用代码示例如下:
//=======================================================================================
//初始化
TArray IntArray; // 创建一个空数组
//=======================================================================================
//增
//使用 Init 初始化数组
IntArray.Init(8, 5); // [8,8,8,8,8]
// 使用 Add 或 Emplace 添加数组元素
// Emplace 可以避免创建不必要的临时变量,效率比 Add 高。
IntArray.Add(5); // ==> [8,8,8,8,8,5]
IntArray.Emplace(3); // ==> [8,8,8,8,8,5,3]
TArray IntArrayB;
IntArrayB.Init(3, 2); // ==> [3,3]
int32 IntArrayC[] = {6, 6};
// 使用 Append 可以将其它的 TArray 或 常规数组 一次性添加在后面。
IntArray.Append(IntArrayB); // ==> [8,8,8,8,8,5,3,3,3]
IntArray.Append(IntArrayC, ARRAY_COUNT(IntArrayC)); // ==> [8,8,8,8,8,5,3,3,3,6,6]
// 使用 AddUnique 添加一个TArray中不存在的元素,如果已经存在则不会添加。
IntArray.AddUnique(1); // ==> [8,8,8,8,8,5,3,3,3,6,6,1]
IntArray.AddUnique(1); // ==> 无法添加
// 使用 Insert 在指定索引处插入元素。
IntArray.Insert(4, 1); // ==> [8,4,8,8,8,8,5,3,3,3,6,6,1]
// 使用 SetNum 设置 TArray 元素数量,如果大于当前数量,则使用元素类型的默认构造函数创建新元素,如果数量小于当前数量,则将移除多余的元素。
// 通常在初始化后分配一个数量。
IntArray.SetNum(5); // ==> [8,4,8,8,8]
IntArray.SetNum(8); // ==> [8,4,8,8,8,0,0,0]
//=======================================================================================
//删
// IntArray == [3,3,6,2,1,3,8,3,7,5]
// 使用 RemoveSingle 只会移除TArray中与传入元素相等的最靠前的一个元素。
IntArray.RemoveSingle(3) // ==> [3,6,2,1,3,8,3]
// 使用 Remove 会移除与传入元素相等的所有元素,
IntArray.Remove(3) // ==> [6,2,1,8,7,5]
// 使用 RemoveAt 按元素索引移除元素,索引必须存在,否则会出现运行时错误。
IntArray.RemoveAt(2) // ==> [6,2,8,7,5]
// 使用 RemoveAll 以 Lambda 表达式的方式来移除具有某些特征的所有元素。
IntArray.RemoveAll([](const int32& Num){Num % 2 == 0}) // ==> [7,5]
// 使用 Pop 移除最后一个元素。
IntArray.Pop(); // ==> [7]
// 使用 Empty 移除数组中所有元素。
IntArray.Empty(); // ==> []
// 使用 Reset 移除数组中所有元素,但不释放内存。
IntArray.Reset(); // ==> []
// 当元素被移除时,其后的元素会向前移,移动过程存在开销。
// 可使用 RemoveSwap、RemoveAtSwap 和 RemoveAllSwap 来减少开销, 通过牺牲剩余元素的排序将不被保证。
//=======================================================================================
//改
//排序
// StringArray == ["!", "Food", "Good", "Hi", "Animal", "Nice"]
// 使用[]索引直接修改值
IntArray[0] = TEXT("?") // ==> ["?", "Food", "Good", "Hi", "Animal", "Nice"]
// 使用 Sort 进行排序
IntArray.Sort() // ==> ["?", "Animal", "Food", "Good", "Hi", "Nice"]
// 使用 Sort 提供 lambda 谓词进行排序
IntArray.Sort([](const FString& A, const FString& B){
return A.Len() < B.Len();
}) // ==> ["?", "Hi", "Good", "Food", "Nice", "Animal"]
// 使用 HeapSort 提供堆排序
IntArray.HeapSort([](const FString& A, const FString& B){
return A.Len() < B.Len();
}) // ==> ["?", "Hi", "Good", "Food", "Nice", "Animal"]
// 使用 StableSort 提供稳定排序,排序后保证等值元素的相对排序。
// 基于 ["!", "Food", "Good", "Hi", "Animal", "Nice"] 排序
IntArray.StableSort([](const FString& A, const FString& B){
return A.Len() < B.Len();
}) // ==> ["?", "Hi", "Food", "Good", "Nice", "Animal"]
//=======================================================================================
//查
//容器操作
// IntArray == [3,6,2,1,8]
// 使用 Num 得到数组的元素数量
int32 Nums = IntArray.Num(); // 目前存了5个元素 ==> Nums == 5
// 使用 GetSlack 找出数组中的Slack量,相当于Max()-Num()
int32 Max = IntArray.Max(); // 目前总共能存22个元素 ==> Max == 22
int32 Slack = IntArray.GetSlack(); // 目前还能存17个元素 ==> Slack == 17
// 使用 Shrink 移除所有Slack。
IntArray.Shrink();
int32 Nums = IntArray.Num(); // ==> Nums == 5
int32 Slack = IntArray.GetSlack(); // ==> Slack == 5
// 使用 GetTypeSize 获取单个元素的大小
uint32 ElementSize = IntArray.GetTypeSize(); // ==> ElementSize == sizeof(uint32)
// 使用 [] 输入元素索引得到元素值
int32 Value = IntArray[2]; // ==> Value == 2
// 使用 Last 反向索引
// StrArr.Top() == StrArr.Last() == StrArr.Last(0)
int32 ElemEndA = StrArr.Last(); // ==> ElemEndA == 8
int32 ElemEndB = StrArr.Last(0);// ==> ElemEndA == 8
int32 ElemEndC = StrArr.Last(1);// ==> ElemEndA == 1
// 使用 Top 得到数组最后一个元素
int32 ElemTop = StrArr.Top(); // ==> ElemEndA == 8
// 当索引小于零或大于等于Num()时,为无效索引,会引起运行时错误。可以使用 IsValidIndex 函数来确定索引是否有效。
bool bIsValid = IntArray.IsValidIndex(-1); // ==> bIsValid == false
bool bIsValid = IntArray.IsValidIndex(2); // ==> bIsValid == true
bool bIsValid = IntArray.IsValidIndex(6); // ==> bIsValid == false
// 判断TArray是否包含某个特定元素,使用 Contains:
bool bIsContain = IntArray.Contains(1); // ==> bIsValid == true
bool bIsContain = IntArray.Contains(4); // ==> bIsValid == false
// 使用 ContainsByPredicate 可以用 Lambda表达式 来判断是否包含具有某些特征的元素。
bool bIsContainByPredicate = IntArray.ContainsByPredicate([](const int32& Num){Num % 2 == 0}) // 存在偶数 ==> true
// 使用 Find 查找某个元素是否存在并返回其索引,FindLast从后往前查找。
int32 Index = IntArray.Find(1); // ==> Index == 3
int32 Index = IntArray.FindLast(1); // ==> Index == 1
int32 Index = IntArray.Find(5); // ==> Index == INDEX_NONE
// 使用 IndexOfByKey 与 Find 类似。
int32 Index = IntArray.IndexOfByKey(1); // ==> Index == 3
int32 Index = IntArray.IndexOfByKey(5); // ==> Index == INDEX_NONE
// 使用 IndexOfByPredicate 可以使用 Lambda表达式 来查找具有某些特征的元素。
int32 Index = IntArray.IndexOfByPredicate([](const int32& Num){Num % 2 == 0}) // 第一个偶数的索引 ==> index == 1
// 使用 FindByKey 可以返回找到的元素的指针
auto* Ptr = IntArray.FindByKey(1); // ==> Ptr == &IntArray[3]
// 使用 FindByPredicate 可以使用 Lambda表达式 来查找具有某些特征的元素的指针。
auto* Ptr = IntArray.FindByPredicate([](const int32& Num){Num % 2 == 0}) // ==> Ptr == &IntArray[1]
// 使用 FilterByPredicate 将会返回一个具有某个特征的元素数组。
auto Filter = IntArray.FilterByPredicate([](const int32& Num){Num % 2 == 0}) // ==> Filter == [6, 2, 8]
// Find是将数组元素转换成你传入的类型在和你传入的数据进行比较。
// IndexOfByKey是直接将数组元素与你传入的数据进行比较。
// Find 函数源码 :
SizeType Find(const ElementType& Item) const
{
const ElementType* RESTRICT Start = GetData();
for (const ElementType* RESTRICT Data = Start, *RESTRICT DataEnd = Data + ArrayNum; Data != DataEnd; ++Data)
{
if (*Data == Item)
{
return static_cast(Data - Start);
}
}
return INDEX_NONE;
}
// IndexOfByKey 函数源码 :
template
SizeType IndexOfByKey(const KeyType& Key) const
{
const ElementType* RESTRICT Start = GetData();
for (const ElementType* RESTRICT Data = Start, *RESTRICT DataEnd = Start + ArrayNum; Data != DataEnd; ++Data)
{
if (*Data == Key)
{
return static_cast(Data - Start);
}
}
return INDEX_NONE;
}
//=======================================================================================
//遍历操作。(注意:遍历时不要做删除操作)
// 基于索引的for循环遍历
for (int32 Index = 0; Index != IntArray.Num(); ++Index)
{
IntArray[Index]; // 遍历的值
}
// auto遍历
for (auto& Int : IntArray)
{
Int; // 遍历的值
}
// 迭代器遍历
// CreateIterator 返回拥有读写访问权限的迭代器,
// CreateConstIterator 返回拥有只读访问权限的迭代器
for (auto It = IntArray.CreateConstIterator(); It; ++It)
{
*It; // 遍历的值
}
//=======================================================================================
//堆
//TArray 拥有支持二叉堆数据结构的函数。
// IntArray == [1,2,3,4,5,6,7,8,9,10]
// 使用 Heapify 将现有数组转换为堆
IntArray.Heapify(); // ==> IntArray == [1,2,4,3,6,5,8,10,7,9]
// 使用 HeapPush 将新元素添加到堆,对其他节点进行重新排序。
IntArray.HeapPush(4); // ==> IntArray == [1,2,4,3,4,5,8,10,7,9,6]
// 使用 HeapPop 移除堆顶结点。
int32 TopNode;
IntArray.HeapPop(TopNode); // ==> TopNode == 1; IntArray == [2,3,4,6,4,5,8,10,7,9]
// 使用 HeapRemoveAt 删除数组中给定索引处的元素,然后重新排列元素。
IntArray.HeapRemoveAt(1); // ==> IntArray == [2,4,4,6,9,5,8,10,7]
// 使用 HeapTop 查看堆的顶部节点,无需变更数组。
int32 Top = IntArray.HeapTop(); // ==> Top == 2