UE-c++ TMap

一. 类介绍

继 TArray 之后,虚幻引擎4(UE4)中最常用的容器是 TMap。TMap 与 TSet 类似,它们的结构均基于对键进行散列运算。但与 TSet 不同的是,此容器将数据存储为键值对(TPair<KeyType, ValueType>),只将键用于存储和获取。

和 TArray 一样,TMap 也是同质容器,就是说它所有元素的类型都应完全相同。TMap 也是值类型,支持通常的复制、赋值和析构函数运算,以及它的元素的强所有权。在映射被销毁时,它的元素都会被销毁。键和值也必须为值类型。

映射有两种类型:TMap 和 TMultiMap。两者之间的不同点是,TMap 中的键是唯一的,而TMultiMap 可存储多个相同的键。在 TMap 中添加新的键值时,若所用的键与原有的对相同,新对将替换原有的对。在 TMultiMap 中,容器可以同时存储新对和原有的对。

是对 std::map/ std::multimap 的增强。

二. 创建TMap

TMap使用了c++的类模板的语法。

	//FString,FString can be replaced with any data type
	TMap<FString,FString>FStringMapFString;

三. TMap函数操作

1. 修改

	FStringMapFString={};
	//The unique key is to add
	FStringMapFString.Add(TEXT("1"),TEXT("A"));
	FStringMapFString.Add(TEXT("2"),TEXT("B"));
	FStringMapFString.Add(TEXT("3"),TEXT("C"));
	PRINTM(FStringMapFString);//[{Key:1,Value:A}{Key:2,Value:B}{Key:3,Value:C}]

	//The duplicate key is to update
	FStringMapFString.Add(TEXT("3"),TEXT("D"));
	PRINTM(FStringMapFString);//[{Key:1,Value:A}{Key:2,Value:B}{Key:3,Value:D}]

	/* You can only add the key, the value is defaulted */
	FStringMapFString.Add(TEXT("4"));
	PRINTM(FStringMapFString);//[{Key:1,Value:A}{Key:2,Value:B}{Key:3,Value:D}{Key:4,Value:}]

	/* Emplace() is the same as TArray's Emplace(),
	 * which can avoid creating temporary objects
	 * when add elements.
	 * Pass the key and value directly to their
	 * respective constructors
	 */
	FStringMapFString.Emplace(TEXT("5"),TEXT("F"));
	PRINTM(FStringMapFString);//[{Key:1,Value:A}{Key:2,Value:B}{Key:3,Value:D}{Key:4,Value:}{Key:5,Value:F}]

	/* Add elements from other TMap containers
	 * The adding process is consistent with the
	 * behavior of Add()
	 */
	TMap<FString,FString>FStringMapFStringOther;
	FStringMapFStringOther.Add(TEXT("5"),TEXT("G"));
	FStringMapFString.Append(FStringMapFStringOther);
	PRINTM(FStringMapFString);//[{Key:1,Value:A}{Key:2,Value:B}{Key:3,Value:D}{Key:4,Value:}{Key:5,Value: G}]
	PRINTM(FStringMapFStringOther);//[{Key:5,Value:G}]

	/* Support move semantics, move the original
	 * mapping to the existing mapping, and the clear
	 * the original mapping
	 */
	FStringMapFString=MoveTemp(FStringMapFStringOther);

2. 迭代

	//C++ Setting range
	for (auto i:FStringMapFString) {
		//PRINT(i.Key+","+i.Value);
	}
	/* Create Iterator
	 * Iterators are divided into four types
	 * readable and writable iterator for key-value
	 * read-only and no write iterator for key-value
	 * readable and writable iterator for key 
	 * read-only and no write iterator for key
	 */
	FStringMapFString.Empty();
	FStringMapFString.Add(TEXT("1"),TEXT("A"));
	FStringMapFString.Add(TEXT("2"),TEXT("B"));

	for (auto i=FStringMapFString.CreateConstIterator();i;++i) {
		PRINT(i.Key()+","+i.Value()+" ");
		//i->Key=TEXT("1");//error
	}
	
	/* Modified content will not be synchronized to the
	 * currently used iterator, It can be said that
	 * next time it will take effect
	 */ 
	for (auto i=FStringMapFString.CreateIterator();i;++i) {
		PRINT(i.Key()+","+i.Value()+" ");
		i->Key=TEXT("2");
	}
	
	/* The parameter is complex, it's not
	 * recommended to use
	 */
	//for(auto i=FStringMapFString.CreateConstKeyIterator();i;++i);
	//for(auto i=FStringMapFString.CreateKeyIterator();i;++i);

	/* GenerateKeyArray(),GenerateValueArray()
	 * can generate arrays contains keys and values.
	 * but the origin arrays will be clear and refilled
	 */
	TArray<FString>StudentKeys;
	TArray<FString>StudentValues;
	FStringMapFString.GenerateKeyArray(StudentKeys);
	FStringMapFString.GenerateValueArray(StudentValues);
	PRINT(StudentKeys[0]);//2
	PRINT(StudentValues[0]);//A

3. 属性

	//Number of elements
	PRINT(FString::FromInt(FStringMapFString.Num()));

4. 查询

	/* Contains() Return whether the collection
	 * contains a specific value
	 */
	bool bResult=FStringMapFString.Contains(TEXT("1"));

	/* You can use operator[] to find the value
	 * corresponding to the specific key.
	 * If it does not exist, it will assert an error
	 */
	//FString Oppo=FStringMapFString[TEXT("1")];

	/* Find() combines the above two to return
	 * a pointer(nullptr) to find the corresponding
	 * value of the specific key
	 */
	FString *TempStringPointer=FStringMapFString.Find(TEXT("1"));

	/* In addition, similar to the Add() function of TArray,
	 * there are a series of auxiliary functions
	 */

	/* FindOrAdd() Can't find a key-value pair that
	 * directly adds a specific key-defaultValue element
	 */
	FString TempString=FStringMapFString.FindOrAdd(TEXT("1"));

	/* FindRef() Return a copy of the specific value
	 * corresponding to the specific key
	 */
	TempString=FStringMapFString.FindRef(TEXT("1"));

	/* FindKey() Reverse search, find a specific key
	 * based on a specific value, return the first key
	 */
	const FString* TempStringConstPointer=FStringMapFString.FindKey(TEXT("1"));

	/* FindChecked() Find the key and return the value
	 * if not, assert an error
	 */
	FStringMapFString.FindChecked(TEXT("1"));

	/* FindAndRemoveChecked() Find the key and return
	 * the value, and remove the key-value pair, if it
	 * does not exist, assert an error
	 */
	FStringMapFString.FindAndRemoveChecked(TEXT("1"));

	/* FindByHash() Search by the hash value of the key */
	//FStringMapFString.FindByHash();

	/* FindOrAddByHash() Search according to the hash
	 * value of the key, if it does not exist, add it
	 */
	//FStringMapFString.FindOrAddByHash();

5. 移除

	/* Remove() Remove specific key-value pairs
	 * and return the number of elements removed
	 * Why?
	 * Because we can directly manipulate data through
	 * iterators, there may be duplicate keys
	 */
	FStringMapFString.Remove(TEXT("1"));

	/* RemoveAndCopyValue() Remove a specific key-value
	 * pair and saves the value to the incoming parameter.
	 * There exists key-value pair ? true : false
	 */
	FStringMapFString.RemoveAndCopyValue(TEXT("1"),TempString);

	/* FindAndRemoveChecked() Find the key and return the value
	 * and remove the key-value pair, assert an error
	 */
	//FStringMapFString.FindAndRemoveChecked();

	/* Empty(),Reset() can clear the mapping
	 * The difference is that Empty() can specify
	 * reserved allocated memory, Reset cannot specify
	 */
	FStringMapFString.Empty(12);
	FStringMapFString.Reset();

6. 排序

	TMap<FString,FString>FStringMapFStringSort;
	FStringMapFStringSort.Emplace(TEXT("3"),TEXT("3"));
	FStringMapFStringSort.Emplace(TEXT("1"),TEXT("1"));
	FStringMapFStringSort.Emplace(TEXT("2"),TEXT("2"));

	/* Sort is combination of multiple sorting,
	 * quick sorting, heap sorting, bubble sorting, etc
	 */
	FStringMapFStringSort.KeySort([](const FString&a,const FString&b) {
		return a.Compare(b)==1?true:false;//Descending
	});
	PRINTM(FStringMapFStringSort);//[{Key:3,Value:3}{Key:2,Value:2}{Key:1,Value:1}]

	FStringMapFStringSort.ValueSort([](const FString&a,const FString&b){
		return a.Compare(b)==1?true:false;//Descending
	});
	PRINTM(FStringMapFStringSort);//[{Key:3,Value:3}{Key:2,Value:2}{Key:1,Value:1}]
	
	/* There is also a stable version of key-value
	 * sorting, merge sort implementation
	 */
	//FStringMapFStringSort.KeyStableSort([](){});
	//FStringMapFStringSort.ValueStableSort([](){});

7. 内存

	TMap<FString,FString>FStringMapFStringSlack;
	
	//Reserve Pre-allocation mapping
	FStringMapFStringSlack.Reserve(10);

	/* Shrink() Remove unused memory, because
	 * it is removed from the end of the container,
	 * unused memory at the beginning or in the middle
	 * will not be removed
	 */
	FStringMapFStringSlack.Shrink();

	/* Compact() Can move all unused memory
	 * to the end of the container, can combined
	 * with Shrink()
	 */
	FStringMapFString.Compact();

	/* CountBytes(),GetAllocatedSize()
	 * is used to analyze memory usage
	 */
	//FStringMapFStringSlack.CountBytes();
	PRINT(FString::FromInt(FStringMapFStringSlack.GetAllocatedSize()));

8. 类键

	//TMap use class/struct as key
	struct FStruct_Rand {
		FString Guid;
		FString A;
		FString B;
		FStruct_Rand() {
			Guid=FGuid::NewGuid().ToString();
		}
	};
	/**
	 * @brief interface
	 * @tparam ValueType value type.
	 * @param KeyInitType key type.
	 * @param FString the type of Tpair key,same as KeyInitType.
	 * @param ElementInitType element type.
	 * @function GetSetKey Returns the element's key.
	 * @function Matches Returns true if A and B are equal, false otherwise.
	 * @function GetKeyHash returns the hash of key.
	 */
	template<typename ValueType>
	struct TStruct_MapKeyFuncs: BaseKeyFuncs<TPair<FStruct_Rand,ValueType>,FString> {
	private:
		typedef BaseKeyFuncs<TPair<FStruct_Rand,ValueType>,FString>Super;
	public:
		typedef typename Super::ElementInitType ElementInitType;
		typedef typename Super::KeyInitType KeyInitType;
		
		static KeyInitType GetSetKey(ElementInitType Element) {
			return Element.Key.Guid;
		}
		
		static bool Matches(KeyInitType A,KeyInitType B) {
			return A.Compare(B,ESearchCase::CaseSensitive)==0;
		}
		
		static uint32 GetKeyHash(KeyInitType Key) {
			return FCrc::StrCrc32(*Key);
		}
	};
	// can then be used as a normal key
	TMap<FStruct_Rand,FString,FDefaultSetAllocator,TStruct_MapKeyFuncs<FString>>CustomMap;

9. 其他自行练习

四. 其他

宏定义真的很好用

	#define PRINT(String) {if (GEngine){GEngine->AddOnScreenDebugMessage(-1,10.0f,FColor::Red,*(String));}}
	#define PRINTA(IntArray) {\
		FString ArrayMessage=TEXT("[");\
		for (auto i=IntArray.begin();i!=IntArray.end();++i){\
			ArrayMessage+=FString::FromInt(*i)+",";\
		}\
		ArrayMessage.RemoveAt(ArrayMessage.Len()-1);\
		PRINT(ArrayMessage+"]");\
	}
	#define PRINTM(FStringMapFString) {\
		FString MapMessage = TEXT("[");\
		for (auto i = FStringMapFString.begin(); i != FStringMapFString.end(); ++i) {\
			MapMessage +=" {Key: "+i->Key + ",";\
			MapMessage +="Value: "+i->Value + "} ";\
		}\
		PRINT(MapMessage+"]");\
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值