Map container: Get Key by given Value?

Hey! I’m trying to find the Key with the provided Values from my Map container. So, the reverse of the “find” node for Maps.

So far I couldn’t find any node for that, and the only solution I found is this:

In my case, it rarely, but it can cause some micro/small lags when I do this. Of course, the lag depends on the length of the Map var.

Since I’d have to do this pretty often isn’t there some more efficient solution to this? Or something from C++ that could be exposed to the blueprint?

The better question is why are you doing this often? It sort of goes against the whole need for a map.
Explain why you need this mechanism that will become very intense computationally.

If you want to do a test if a key has been used (and you don’t want to overwrite the set value) then keep an array of used keys in parallel and use that as your guide instead of hammering a map for something it is not intended to be used for.

You could use this combination of functions if you are dead set on this

I wrote a quick test in a static lib and it works as intended

.h

UFUNCTION(BlueprintCallable)
		static bool FindByValue(TMap<FString, FString> passedMap, FString NeededValue);

.cpp

bool UMapTool::FindByValue(TMap<FString, FString> passedMap, FString NeededValue) {
	TArray<FString> out;
	passedMap.GenerateValueArray(out);
	return out.Contains(NeededValue);
}

It flatters the maps values to a single array which you can just use contains on. It should be optimized & beats iterating over keys => values to get it.

Though I’d still have to read up how to convert it to take in a generic TMap. (might require a custom k2Node).

Seems templates are a pain in ue from the c++ side. For now do a stiff implementation of the needed TMap. If I find a way to use it with templates I will update my answer. (Seems you can have T templates but it won’t expose it to blueprints)

Here is the equivalent in BP but not sure about the performance.

Hi, thanks for the answer!

I need it because there are situations where I only have the Value part of the container, and if I want to modify the Map, I would need the Key for it.

I’ll probably just create another Map container but with the Value as the Key, and the Key as the Value. So this way I can search back and forth. This isn’t the best solution, and it’d be great if a Find Key by Value node existed.

I tried something like this except, instead of the “contains” I used the “find” node.
The only problem with this was that the order wasn’t the same as the actual Map.

Maps in their structures have no order. Thats why they are so fast. You won’t find a maps key => val index because intenally it has none.

Edit:Ok so how about you have a second map in parallel that has mirror key values.

You would need a custom setter that would work like this

Set(key, val){
MapA[key] = val;
MapB[val] = key;

}

And when you want the reverse lookup just do a get from MapB

Its a bit of a hassle but keeps the speed of access if the map and should not slow down as it grows.

1 Like

Yeah, exactly! Just like what I mentioned above:

I made it and it turns out it works great. As you said it is a bit of a hassle, but if it works. :person_shrugging: