Search code examples
sqf

How to emulate an hash table in SQF?


FYI: SQF is a programming language for the computer game series Arma.

The main data types of SQF are documented and the list does not include an hash table (or dictionary).

One way to have a hash table is to create a Game Logic in the mission.sqm (e.g. named logic1), and use setVariable and getVariable on it, e.g.

logic1 setVariable ["variable1", 1];
_a = logic1 getVariable "variable1";

However, this requires an extra array associated with it to track the list of used keys, e.g.

logic1Vars = [];
logic1 setVariable ["variable1", 1];
logic1Vars pushBack "variable1";

logic1 setVariable ["variable1", nil];
logic1Vars = logic1Vars - ["variable1"];

(or is there a way to get the list of variables?)

Another way (that is possible but I haven't tried) is to implement an hash table. That obviously takes an extra effort because implementing a good table is not easy.

But maybe I am missing something: is there an idiomatic way to have an hash table in SQF?


Solution

  • You can use allVariables to retrieve the Number of keys in a Namespace.

    To create a Namespace you can use a Logic or a Location or a SimpleObject. See how CBA does it https://github.com/CBATeam/CBA_A3/blob/master/addons/common/fnc_createNamespace.sqf.

    Generally a Location or SimpleObject is more Performance friendly than using a GameLogic. You should keep that in Mind.

    But what you are probably searching for is the allVariables command which returns all Variables in a Namespace(Hashtable).

    You can also use getVariable ARRAY to set a default Value in case the Namespace doesn't contain the Key you want to read.

    CBA also has Hashes they behave like a Map. Not like a hashTable (The keys are not hashed) also it's SQF code instead of Engine code so it is slightly slower.

    Also (don't have enough reputation to comment) You don't need all of this:

    _vars = _logic getVariable "_VARIABLES";
    _vars pushBack "variable1";
    _logic setVariable ["_VARIABLES", _vars];
    

    _vars will be a reference to the Array and pushBack will add an element to that Array you are referring to. so pushBack is already modifying _VARIABLES. No need to set it again.