How to emulate a hash table in SQF?

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

The basic SQF datatypes are documented and the list does not contain a hash table (or dictionary).

One way to have a hash table is to create the game logic in mission.sqm

(for example with a name logic1

) and use on it setVariable

and getVariable

, for example

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

      

However, this requires an additional array associated with it to keep track of the list of keys used, eg.

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 (maybe, but I haven't tried) is to implement a hash table. This obviously requires additional effort, because implementing a good table is not easy.

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

+3


source to share


2 answers


You can use allVariables to retrieve the number of keys in the namespace.

To create namespace you can use logic or location or SimpleObject. Check out how CBA does it https://github.com/CBATeam/CBA_A3/blob/master/addons/common/fnc_createNamespace.sqf .

Generally, Location or SimpleObject is more performance friendly than using GameLogic. You must keep it in Mind.

But what you are probably looking for is the allVariables command, which returns all variables in the namespace (Hashtable).

You can also use getVariable ARRAY

to set the default if the namespace does not contain the key you want to read.



CBA also has Hashes

them behave like a card. Doesn't look like hashTable (keys are not hashed) and also SQF code instead of engine code, so it's a little slower.

Also (not enough reputation for comments) You don't need all of this:

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

      

_vars will be a reference to an array, and pushBack will add an item to that array you are referring to. so pushBack is already modifying _VARIABLES

. Don't need to install it again.

+3


source


One way to create a hash table without having to create one mission.sqm

is through scripting. In particular, one can write

allHashes = createGroup west;  // somewhere once; `west` or `east` does not matter here.

_logic = allHashes createUnit ["LOGIC", [0,0,0], [], 0, "NONE"];
_logicVars = [];

      

it still requires a list of variables and thus does not encapsulate the entire hash table into a single object. One way to achieve hash table logic in one object is to use

_logic = allHashes createUnit ["LOGIC", [0,0,0], [], 0, "NONE"];
_logic setVariable ["_VARIABLES", []];

      



and use

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

      

This could be encapsulated into a function, but still needs 4 lines of code to get it all ...

0


source







All Articles