• (转载)UE4容器TArray、TMap的使用


     

    目录(?)[+]

     

    ue中特有容器的使用

    1、Log日志宏

    输出到屏幕上的调试日志会覆盖,在output log窗口则可以全部显示,所以先写个打日志的宏

    DECLARE_LOG_CATEGORY_EXTERN(MyContaimTest, Log, All);
    DEFINE_LOG_CATEGORY(MyContaimTest)

    //调试日志
    UE_LOG(MyContaimTest, Warning, TEXT("--- index:%d, value:%s "),i, *_arr[i]);

    2、TArray的几种遍历

        auto printFunc1 = [&](TArray<FString>& _arr)->void{
    for (int32 i = 0; i < _arr.Num(); i++)
    {
    //FString str = FString::Printf(TEXT("--- index:%d, value:%s "), i, *_arr[i]);
    //GEngine->AddOnScreenDebugMessage(0, 3.0f, FColor::Red, str);
    UE_LOG(MyContaimTest, Warning, TEXT("--- index:%d, value:%s "),i, *_arr[i]);
    }
    };

    auto printFunc2 = [&](TArray<FString>& _arr)->void {
    for (const FString& val : _arr)
    {
    UE_LOG(MyContaimTest, Warning, TEXT("--- value111:%s"), *val);
    }
    };

    auto printFunc3 = [&](TArray<FString>& _arr)->void {
    for (TArray<FString>::TConstIterator iter = _arr.CreateConstIterator(); iter; ++iter)
    {
    UE_LOG(MyContaimTest, Warning, TEXT("--- value222:%s"), *(*iter));
    }
    };

    3、TArray 增

        // 创建一个数组
    TArray<int32> IntArray;

    // 通过同一个元素填充初始化
    IntArray.Init(10, 5);
    // IntArray == [10, 10, 10, 10, 10]

    // 增加新元素
    // Add会引入临时对象,优先使用Emplace
    TArray<FString> StrArr;
    StrArr.Add(TEXT("Hello"));
    StrArr.Emplace(TEXT("World"));
    // StrArr == ["Hello", "World"]
    //printFunc1(StrArr);

    // 追加多个元素
    FString Arr[] = { TEXT("of"), TEXT("Tomorrow") };
    StrArr.Append(Arr, ARRAY_COUNT(Arr));
    // StrArr == ["Hello", "World", "of", "Tomorrow"]
    //printFunc1(StrArr);

    // 只有容器中不存在该元素的时候,才添加
    StrArr.AddUnique(TEXT("!"));
    // StrArr = ["Hello", "World", "of", "Tomorrow", "!"]
    //printFunc1(StrArr);
    StrArr.AddUnique(TEXT("!"));
    // StrArr没有变
    //printFunc1(StrArr);

    // 插入
    StrArr.Insert(TEXT("Brave"), 1);
    // StrArr == ["Hello","Brave","World","of","Tomorrow","!"]
    //printFunc1(StrArr);

    // 直接设置数组的元素个数
    // 如果大于当前值,那么使用元素类型的默认构造函数创建新元素
    // 如果下雨当前值,相当于删除元素
    StrArr.SetNum(8);
    // StrArr == ["Hello","Brave","World","of","Tomorrow","!","",""]
    //printFunc1(StrArr);

    StrArr.SetNum(6);
    // StrArr == ["Hello","Brave","World","of","Tomorrow", "!"]
    //printFunc1(StrArr);
    //printFunc2(StrArr);
    //printFunc3(StrArr);

    4、TArray 排序

        // 排序(快排序,不稳定的)
    // 默认按照operator <
    StrArr.Sort();
    // StrArr == ["!","Brave","Hello","of","Tomorrow","World"]

    // 自定义排序规则
    StrArr.Sort([](const FString& A, const FString& B) {
    return A.Len() < B.Len();
    });
    // StrArr == ["!","of","Hello","Brave","World","Tomorrow"]
    //printFunc1(StrArr);

    // 堆排序(也不稳定的)
    StrArr.HeapSort([](const FString& A, const FString& B) {
    return A.Len() < B.Len();
    });
    // StrArr == ["!","of","Brave","Hello","World","Tomorrow"]
    //printFunc1(StrArr);

    // 合并排序(稳定的)
    StrArr.StableSort([](const FString& A, const FString& B) {
    return A.Len() < B.Len();
    });
    // StrArr == ["!","of","Brave","Hello","World","Tomorrow"]
    //printFunc1(StrArr);

    5、TArray 查

        // 查询
    // 数量
    int32 Count = StrArr.Num();
    // Count == 6

    // 直接访问
    // 如果容器是const,那么返回的指针也是const的
    FString* StrPtr = StrArr.GetData();
    // StrPtr[0] == "!"
    // StrPtr[1] == "of"
    // ...

    // 一个元素的大小
    uint32 ElementSize = StrArr.GetTypeSize();
    // ElementSize == sizeof(FString)

    // 判断索引
    bool bValidM1 = StrArr.IsValidIndex(-1);
    // bValidM1 == false

    // operator[] 返回索引
    //StrArr[3] = StrArr[3].ToUpper();
    // StrArr == ["!","of","Brave","HELLO","World","Tomorrow"]

    // 从后面访问
    FString ElemEnd = StrArr.Last();
    FString ElemEnd0 = StrArr.Last(0);
    FString ElemEnd1 = StrArr.Last(1);
    FString ElemTop = StrArr.Top();
    // ElemEnd == "Tomorrow"
    // ElemEnd0 == "Tomorrow"
    // ElemEnd1 == "World"
    // ElemTop == "Tomorrow"

    // 查询是否存在某元素
    bool bHello = StrArr.Contains(TEXT("Hello"));
    bool bGoodbye = StrArr.Contains(TEXT("Goodbye"));
    // bHello == true
    // bGoodbye == false

    // 自定义查询规则
    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

    // 查找,返回索引
    int32 Index;
    if (StrArr.Find(TEXT("Hello"), Index))
    {
    // Index == 3
    }
    int32 IndexLast;
    if (StrArr.FindLast(TEXT("Hello"), IndexLast))
    {
    // IndexLast == 3, because there aren't any duplicates
    }
    // 还可以直接返回index, 如果找不到会返回INDEX_NONE
    int32 Index2 = StrArr.Find(TEXT("Hello"));
    int32 IndexLast2 = StrArr.FindLast(TEXT("Hello"));
    int32 IndexNone = StrArr.Find(TEXT("None"));
    // Index2 == 3
    // IndexLast2 == 3
    // IndexNone == INDEX_NONE

    // 还可以用IndexOfByKey, 采用operator==(ElementType, KeyType)比较
    int32 Index3 = StrArr.IndexOfByKey(TEXT("Hello"));
    // Index == 3

    int32 Index4 = StrArr.IndexOfByPredicate([](const FString& Str) {
    return Str.Contains(TEXT("r"));
    });
    // Index == 2

    // 除了返回索引,也可以返回指针
    auto* OfPtr = StrArr.FindByKey(TEXT("of"));
    auto* ThePtr = StrArr.FindByKey(TEXT("the"));
    // OfPtr == &StrArr[1]
    // ThePtr == nullptr

    auto* Len5Ptr = StrArr.FindByPredicate([](const FString& Str) {
    return Str.Len() == 5;
    });
    auto* Len6Ptr = StrArr.FindByPredicate([](const FString& Str) {
    return Str.Len() == 6;
    });
    // Len5Ptr == &StrArr[2]
    // Len6Ptr == nullptr

    6、TArray 删

    // 删除所有匹配的元素
    StrArr.Remove(TEXT("hello"));
    // StrArr == ["!","of","Brave","World","Tomorrow"]
    StrArr.Remove(TEXT("goodbye"));
    // StrArr is unchanged, as it doesn't contain "goodbye"

    // 删除最后的元素
    StrArr.Pop();
    // StrArr == ["!", "of", "Brave", "World"]

    // 删除第一个匹配元素
    TArray<int32> ValArr;
    int32 Temp[] = { 10, 20, 30, 5, 10, 15, 20, 25, 30 };
    ValArr.Append(Temp, ARRAY_COUNT(Temp));
    // ValArr == [10,20,30,5,10,15,20,25,30]

    ValArr.Remove(20);
    // ValArr == [10,30,5,10,15,25,30]
    ValArr.RemoveSingle(30);
    // ValArr == [10,5,10,15,25,30]
    // 通过索引删除
    ValArr.RemoveAt(2); // Removes the element at index 2
    // ValArr == [10,5,15,25,30]
    //ValArr.RemoveAt(99);
    // This will cause a runtime error as
    // there is no element at index 99

    // 条件删除
    ValArr.RemoveAll([](int32 Val) {
    return Val % 3 == 0;
    });
    // ValArr == [10,5,25]

    // 如果删除元素之后无顺序要求,可以用更高效的方法
    //原理:把最后的元素移动到被删除的地方,这样就无需移动 被删除元素以后的元素
    TArray<int32> ValArr2;
    for (int32 i = 0; i != 10; ++i)
    ValArr2.Add(i % 5);
    // ValArr2 == [0,1,2,3,4,0,1,2,3,4]

    ValArr2.RemoveSwap(2); //删除等于2的元素
    // ValArr2 == [0,1,4,3,4,0,1,3]

    ValArr2.RemoveAtSwap(1); //删除索引为1的元素
    // ValArr2 == [0,3,4,3,4,0,1]

    ValArr2.RemoveAllSwap([](int32 Val) { //删除所有3的倍数
    return Val % 3 == 0;
    });
    // ValArr2 == [1,4,4]

    // 清空
    ValArr2.Empty();
    // ValArr2 == []

    7、TArray 支持的操作符, 也支持move语义

    TArray<int32> ValArr3;
    ValArr3.Add(1);
    ValArr3.Add(2);
    ValArr3.Add(3);

    auto ValArr4 = ValArr3;
    // ValArr4 == [1,2,3];
    ValArr4[0] = 5;
    // ValArr3 == [1,2,3];
    // ValArr4 == [5,2,3];

    ValArr4 += ValArr3;
    // ValArr4 == [5,2,3,1,2,3]

    // move语义,源数组会被清空
    ValArr3 = MoveTemp(ValArr4);
    // ValArr3 == [5,2,3,1,2,3]
    // ValArr4 == []

    TArray<FString> FlavorArr1;
    FlavorArr1.Emplace(TEXT("Chocolate"));
    FlavorArr1.Emplace(TEXT("Vanilla"));
    // FlavorArr1 == ["Chocolate","Vanilla"]

    auto FlavorArr2 = FlavorArr1;
    // FlavorArr2 == ["Chocolate","Vanilla"]
    bool bComparison1 = FlavorArr1 == FlavorArr2;
    // bComparison1 == true
    if (bComparison1)
    UE_LOG(MyContaimTest, Warning, TEXT("--- FlavorArr1 == FlavorArr2"));

    for (auto& Str : FlavorArr2)
    {
    Str = Str.ToUpper();
    }
    // FlavorArr2 == ["CHOCOLATE","VANILLA"]

    bool bComparison2 = FlavorArr1 == FlavorArr2;
    // bComparison2 == true, because FString comparison ignores case
    if (bComparison2)
    UE_LOG(MyContaimTest, Warning, TEXT("--- FlavorArr1 == FlavorArr2 too"));

    Exchange(FlavorArr2[0], FlavorArr2[1]); //交换两个元素
    // FlavorArr2 == ["VANILLA","CHOCOLATE"]
    bool bComparison3 = FlavorArr1 == FlavorArr2;
    // bComparison3 == false, because the order has changed

    8、TArray 堆排序

    // 堆
    TArray<int32> HeapArr;
    for (int32 Val = 10; Val != 0; --Val)
    HeapArr.Add(Val);
    // HeapArr == [10,9,8,7,6,5,4,3,2,1]
    HeapArr.Heapify();
    // HeapArr == [1,2,4,3,6,5,8,10,7,9]

    HeapArr.HeapPush(4);
    // HeapArr == [1,2,4,3,4,5,8,10,7,9,6]
    int32 TopNode;
    HeapArr.HeapPop(TopNode);
    // TopNode == 1
    // HeapArr == [2,3,4,6,4,5,8,10,7,9]
    HeapArr.HeapRemoveAt(1);
    // HeapArr == [2,4,4,6,9,5,8,10,7]
    int32 Top = HeapArr.HeapTop();
    // Top == 2

    9、TArray动态增长

        // slack
    // GetSlack() is equivalent to Max() - Num():
    TArray<int32> SlackArray;
    // SlackArray.GetSlack() == 0
    // SlackArray.Num() == 0
    // SlackArray.Max() == 0
    //printFunc1(SlackArray);

    SlackArray.Add(1);
    // SlackArray.GetSlack() == 3
    // SlackArray.Num() == 1
    // SlackArray.Max() == 4
    //printFunc1(SlackArray);

    SlackArray.Add(2);
    SlackArray.Add(3);
    SlackArray.Add(4);
    SlackArray.Add(5);
    // SlackArray.GetSlack() == 17
    // SlackArray.Num() == 5
    // SlackArray.Max() == 22
    //printFunc1(SlackArray); //重新分配内存的公式Retval = NumElements + 3*NumElements/8 + 16;

    SlackArray.Empty(); //内存也清空
    // SlackArray.GetSlack() == 0
    // SlackArray.Num() == 0
    // SlackArray.Max() == 0
    //printFunc1(SlackArray);

    SlackArray.Empty(3);//只是清空元素,内存还在
    // SlackArray.GetSlack() == 3
    // SlackArray.Num() == 0
    // SlackArray.Max() == 3

    SlackArray.Add(1);
    SlackArray.Add(2);
    SlackArray.Add(3);
    // SlackArray.GetSlack() == 0
    // SlackArray.Num() == 3
    // SlackArray.Max() == 3

    SlackArray.Reset(0); //只是清空元素,内存还在
    // SlackArray.GetSlack() == 3
    // SlackArray.Num() == 0
    // SlackArray.Max() == 3
    SlackArray.Reset(10);//大于当前的Max(10>3),重新分配内存
    // SlackArray.GetSlack() == 10
    // SlackArray.Num() == 0
    // SlackArray.Max() == 10

    SlackArray.Add(5);
    SlackArray.Add(10);
    SlackArray.Add(15);
    SlackArray.Add(20);
    // SlackArray.GetSlack() == 6
    // SlackArray.Num() == 4
    // SlackArray.Max() == 10
    SlackArray.Shrink(); //缩减内存到当前元素的个数
    // SlackArray.GetSlack() == 0
    // SlackArray.Num() == 4
    // SlackArray.Max() == 4

    10、TMap的几种遍历

        auto printFunc1 = [&](TMap<int32, FString>& _map)->void {
    for (TPair<int32, FString>& element : _map)
    {
    UE_LOG(MyContaimTest, Warning, TEXT("--- key:%d, value111:%s "),
    element.Key, *element.Value);
    }
    };

    auto printFunc2 = [&](TMap<int32, FString>& _map)->void {
    for (TMap<int32, FString>::TConstIterator iter = _map.CreateConstIterator(); iter; ++iter)
    {
    UE_LOG(MyContaimTest, Warning, TEXT("--- key:%d, value222:%s "),
    iter->Key, *iter->Value);
    }
    };

    auto printFunc3= [&](TMap<int32, FString>& _map)->void {
    for (TMap<int32, FString>::TConstIterator iter(_map); iter; ++iter)
    {
    UE_LOG(MyContaimTest, Warning, TEXT("--- key:%d, value222:%s "),
    iter->Key, *iter->Value);
    }
    };

    11、TMap 增

        // 创建
    // key比较使用==
    // hashcode计算使用GetTypeHash
    TMap<int32, FString> FruitMap;

    FruitMap.Add(5, TEXT("Banana"));
    FruitMap.Add(2, TEXT("Grapefruit"));
    FruitMap.Add(7, TEXT("Pineapple"));
    // FruitMap == [
    // { Key: 5, Value: "Banana" },
    // { Key: 2, Value: "Grapefruit" },
    // { Key: 7, Value: "Pineapple" }
    // ]
    FruitMap.Add(2, TEXT("Pear")); //相同key值,顶掉value
    // FruitMap == [
    // { Key: 5, Value: "Banana" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" }
    // ]

    FruitMap.Add(4);//没有value值,会构造一个默认值进去
    // FruitMap == [
    // { Key: 5, Value: "Banana" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" },
    // { Key: 4, Value: "" }
    // ]

    FruitMap.Emplace(3, TEXT("Orange"));
    // FruitMap == [
    // { Key: 5, Value: "Banana" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" },
    // { Key: 4, Value: "" },
    // { Key: 3, Value: "Orange" }
    // ]

    TMap<int32, FString> FruitMap2;
    FruitMap2.Emplace(4, TEXT("Kiwi"));
    FruitMap2.Emplace(9, TEXT("Melon"));
    FruitMap2.Emplace(5, TEXT("Mango"));
    FruitMap.Append(FruitMap2); //已有的会顶掉,没有就完后叠
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" }
    // ]
    //printFunc1(FruitMap);

    12、TMap 查

    //---------- 通过key查找到value
    // 查询
    int32 Count = FruitMap.Num();
    // Count == 6

    FString Val7 = FruitMap[7];
    // Val7 == "Pineapple"
    //FString Val8 = FruitMap[8]; // assert!//查找不存在的会造成运行时崩溃

    bool bHas7 = FruitMap.Contains(7);
    bool bHas8 = FruitMap.Contains(8);
    // bHas7 == true
    // bHas8 == false

    FString* Ptr7 = FruitMap.Find(7); //返回的是value的指针
    FString* Ptr8 = FruitMap.Find(8);
    // *Ptr7 == "Pineapple"
    // Ptr8 == nullptr

    FString& Ref7 = FruitMap.FindOrAdd(7); //返回的是引用
    // Ref7 == "Pineapple"
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" }
    // ]

    FString& Ref8 = FruitMap.FindOrAdd(8); //不存在则构造一个添加进去,返回引用
    // Ref8 == ""
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" },
    // { Key: 8, Value: "" }
    // ]

    FString Val10 = FruitMap.FindRef(7); //存在则复制拷贝到变量中,不存在则变量自己构造
    FString Val9 = FruitMap.FindRef(6);
    // Val10 == "Pineapple"
    // Val9 == ""
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" },
    // { Key: 8, Value: "" }
    // ]

    //---------- 通过value查找到key
    const int32* KeyMangoPtr = FruitMap.FindKey(TEXT("Mango"));
    const int32* KeyKumquatPtr = FruitMap.FindKey(TEXT("Kumquat"));
    // *KeyMangoPtr == 5
    // KeyKumquatPtr == nullptr

    TArray<int32> FruitKeys;
    TArray<FString> FruitValues;
    FruitMap.GenerateKeyArray(FruitKeys); //生成key、value数组
    FruitMap.GenerateValueArray(FruitValues);
    // FruitKeys == [ 5,2,7,4,3,9,8 ]
    // FruitValues == [ "Mango","Pear","Pineapple","Kiwi","Orange",
    // "Melon","" ]

    13、TMap 删

    FruitMap.Remove(8);
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 2, Value: "Pear" },
    // { Key: 7, Value: "Pineapple" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" }
    // ]

    FString Removed7 = FruitMap.FindAndRemoveChecked(7); //查找并移除
    // Removed7 == "Pineapple"
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 2, Value: "Pear" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" }
    // ]

    //FString Removed8 = FruitMap.FindAndRemoveChecked(8); // assert!不存在,运行时崩溃

    FString Removed;
    bool bFound2 = FruitMap.RemoveAndCopyValue(2, Removed); //存在这个拷贝数据,返回true
    // bFound2 == true
    // Removed == "Pear"
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" }
    // ]

    bool bFound8 = FruitMap.RemoveAndCopyValue(8, Removed); //不存在,则不改变Removed的值,返回false
    // bFound8 == false
    // Removed == "Pear", i.e. unchanged
    // FruitMap == [
    // { Key: 5, Value: "Mango" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" }
    // ]

    TMap<int32, FString> FruitMapCopy = FruitMap;
    // FruitMapCopy == [
    // { Key: 5, Value: "Mango" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" },
    // { Key: 9, Value: "Melon" }
    // ]

    FruitMapCopy.Empty();//清空
    // FruitMapCopy == []

    14、TMap 排序

        // 排序
    FruitMap.KeySort([](int32 A, int32 B) {
    return A > B; // sort keys in reverse
    });
    // FruitMap == [
    // { Key: 9, Value: "Melon" },
    // { Key: 5, Value: "Mango" },
    // { Key: 4, Value: "Kiwi" },
    // { Key: 3, Value: "Orange" }
    // ]

    FruitMap.ValueSort([](const FString& A, const FString& B) {
    return A.Len() < B.Len(); // sort strings by length
    });
    // FruitMap == [
    // { Key: 4, Value: "Kiwi" },
    // { Key: 5, Value: "Mango" },
    // { Key: 9, Value: "Melon" },
    // { Key: 3, Value: "Orange" }
    // ]
    //printFunc3(FruitMap);

    15、TMap 支持的操作符, 也支持move语义

        // 操作符
    TMap<int32, FString> NewMap = FruitMap;
    NewMap[5] = "Apple";
    NewMap.Remove(3);
    // NewMap == [
    // { Key: 4, Value: "Kiwi" },
    // { Key: 5, Value: "Apple" },
    // { Key: 9, Value: "Melon" }
    // ]

    FruitMap = MoveTemp(NewMap); //move
    // FruitMap == [
    // { Key: 4, Value: "Kiwi" },
    // { Key: 5, Value: "Apple" },
    // { Key: 9, Value: "Melon" }
    // ]
    // NewMap == []

    // Slack
    FruitMap.Reset();//内存也清空
    // FruitMap == [<invalid>, <invalid>, <invalid>]
    printFunc1(FruitMap);

    FruitMap.Reserve(10);//预设了10个大小的内存,add时候从后往前叠;没有FruitMap.Reserve(10);则是从前往后叠
    for (int32 i = 0; i != 10; ++i)
    {
    FruitMap.Add(i, FString::Printf(TEXT("Fruit%d"), i));
    }
    // FruitMap == [
    // { Key: 9, Value: "Fruit9" },
    // { Key: 8, Value: "Fruit8" },
    // ...
    // { Key: 1, Value: "Fruit1" },
    // { Key: 0, Value: "Fruit0" }
    // ]
    //printFunc1(FruitMap);

    for (int32 i = 0; i != 10; i += 2)
    {
    FruitMap.Remove(i); //移除后,还是有内存占用
    }
    // FruitMap == [
    // { Key: 9, Value: "Fruit9" },
    // <invalid>,
    // { Key: 7, Value: "Fruit7" },
    // <invalid>,
    // { Key: 5, Value: "Fruit5" },
    // <invalid>,
    // { Key: 3, Value: "Fruit3" },
    // <invalid>,
    // { Key: 1, Value: "Fruit1" },
    // <invalid>
    // ]
    //printFunc1(FruitMap);

    FruitMap.Shrink();//移除最后又一个有效内存 后的 所有无效的内存占用
    // FruitMap == [
    // { Key: 9, Value: "Fruit9" },
    // <invalid>,
    // { Key: 7, Value: "Fruit7" },
    // <invalid>,
    // { Key: 5, Value: "Fruit5" },
    // <invalid>,
    // { Key: 3, Value: "Fruit3" },
    // <invalid>,
    // { Key: 1, Value: "Fruit1" }
    // ]
    //printFunc1(FruitMap);

    FruitMap.Compact(); //把无效的都丢到后面
    // FruitMap == [
    // { Key: 9, Value: "Fruit9" },
    // { Key: 7, Value: "Fruit7" },
    // { Key: 5, Value: "Fruit5" },
    // { Key: 3, Value: "Fruit3" },
    // { Key: 1, Value: "Fruit1" },
    // <invalid>,
    // <invalid>,
    // <invalid>,
    // <invalid>
    // ]
    FruitMap.Shrink();
    // FruitMap == [
    // { Key: 9, Value: "Fruit9" },
    // { Key: 7, Value: "Fruit7" },
    // { Key: 5, Value: "Fruit5" },
    // { Key: 3, Value: "Fruit3" },
    // { Key: 1, Value: "Fruit1" }
    // ]

    16、TMap 自定义key

    struct FMyStruct
    {
    // String which identifies our key
    FString UniqueID;

    // Some state which doesn't affect struct identity
    float SomeFloat;

    explicit FMyStruct(float InFloat)
    : UniqueID(FGuid::NewGuid().ToString())
    , SomeFloat(InFloat)
    {
    }
    };
    template <typename ValueType>
    struct TMyStructMapKeyFuncs :
    BaseKeyFuncs<
    TPair<FMyStruct, ValueType>,
    FString
    >
    {
    private:
    typedef BaseKeyFuncs<
    TPair<FMyStruct, ValueType>,
    FString
    > Super;

    public:
    typedef typename Super::ElementInitType ElementInitType;
    typedef typename Super::KeyInitType KeyInitType;

    static KeyInitType GetSetKey(ElementInitType Element)
    {
    return Element.Key.UniqueID;
    }

    static bool Matches(KeyInitType A, KeyInitType B)
    {
    return A.Compare(B, ESearchCase::CaseSensitive) == 0;
    }

    static uint32 GetKeyHash(KeyInitType Key)
    {
    return FCrc::StrCrc32(*Key);
    }
    };

    // 自定义key
    TMap < FMyStruct, int32,
    FDefaultSetAllocator, TMyStructMapKeyFuncs < int32 >> MyMapToInt32;

    // Add some elements
    MyMapToInt32.Add(FMyStruct(3.14f), 5);
    MyMapToInt32.Add(FMyStruct(1.23f), 2);

    // MyMapToInt32 == [
    // {
    // Key: {
    // UniqueID: "D06AABBA466CAA4EB62D2F97936274E4",
    // SomeFloat: 3.14f
    // },
    // Value: 5
    // },
    // {
    // Key: {
    // UniqueID: "0661218447650259FD4E33AD6C9C5DCB",
    // SomeFloat: 1.23f
    // },
    // Value: 5
    // }
    // ]

    17、TMultiMap 查(用法大致和TMap相同)

        TMultiMap<int32, FString> mtMap1;
    mtMap1.Add(5, TEXT("aaa"));
    mtMap1.Add(3, TEXT("bbb"));
    mtMap1.Add(7, TEXT("ccc"));
    mtMap1.Add(6, TEXT("ddd")); //添加三个相同的key值得键值对
    mtMap1.Add(6, TEXT("eee"));
    mtMap1.Add(6, TEXT("fff"));

    printFunc1(mtMap1);
    //printFunc2(mtMap1);
    //printFunc1(mtMap1)
    TArray<FString> values;
    mtMap1.MultiFind(6, values); //找出所以key为6的value,并丢到values数组中
    // values == ["fff","eee","ddd"]
    printArrFunc1(values);

    //mtMap1.Empty();

    18、数组

    FString strVec[2] = {"aa", bbb"};
    int32 num = ARRAY_COUNT(strVec); //使用宏ARRAY_COUNT统计数组里的个数

    19、TArray,TMap可以在遍历中删除,数组的num

    for (int32 i = 0;i < mArr.Num (); ++i)
    {
    if (mArr [i] == 222)
    {
    mArr.RemoveAt (i);
    }
    }

    for (auto Iter = map1.CreateIterator (); Iter;++ Iter)
    {
    UE_LOG(GolbalFuncLogger, Warning , TEXT("--- %d, %s"), Iter->Key , *Iter-> Value);
    if (Iter ->Key == 3)
    {
    Iter.RemoveCurrent ();
    }
    }

    a
     
  • 相关阅读:
    Docker版安装部署 Nexus 及阿里云仓库与本地仓库配置
    Golang开发中如何解决共享变量问题
    什么是dubbo?
    dubbo配置
    redis击穿,穿透,雪崩
    C#根据wsdl文件生成客户端调用代码
    查询哪个程序在使用某个端口
    Java面试题(十六):双亲委派模型
    Java面试题(十五):Java类加载器
    Java面试题(十四):什么是字节码?采用字节码的好处是什么?
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/8336966.html
Copyright © 2020-2023  润新知