Tables - Hashmap Usage
Replacing Arrays with Hashmaps
In Lua, a table is, at its core, composed of two components.
- An array (otherwise referred to as a list or sequential table)
- A hashmap (otherwise referred to as a dictionary)
An array is a linear sequence of elements, so:
As you can see were purely defining elements and letting the language determine the keys for us. This is useful in situations where you dont have a necessarily deterministic way of retrieving this data. If for instance we wanted to find the player named "Jeff"
in the following array declaration.
We could do the following:
But this seems a little sloggish, doesn't it? Why do we have to iterate over every single person in array
to just find one! Although this may be performant, and work just fine in most cases, why is there not an easier way?... well there is! This is where we get into hashmaps!
Imagine this being structured a little differently, where instead of the player index being tied to where/when it was defined in the table, it is the name!
This may seem like a benign change considering you can treat this nearly identically to the old solution to finding the player, but this opens up an entirely new way!
No need for iteration, makes life substantially better considering you now can find values without the need for a function to return them, or a temporary variable to set the found player too after iteration.
Notes
Dots vs Brackets
As you read above, we did hash["Jeff"]
to retrieve Jeff from the table, but everywhere in the API when you get something from a table you do vgui.Create
, not vgui["Create"]
... Right? Well they're the same thing, the only difference is the syntax and one has a magic power. That power is allowing you to use an "Expression" (a piece of code that returns something) to index instead of a constant value, so.
Yes, in this case, it is useless; however, this is extremely powerful, probably the most powerful thing about hashmaps entirely. Allowing you to dynamically index values makes it so you can use user input to find a value, get a player by its internal values you can only know at runtime, ect. You couldnt do the following could you?
It doesnt make sense!
ipairs
The ipairs iterator function is used the exact same way as page>Global.pairspage/>, except ipairs only iterates through sequential keys. Meaning, if it runs across nil
in the sequential portion of a table, it will stop iterating.
This would output A B
, not A B D
, because it encountered nil
on key 3
. The workaround for this is
- Using pairs, which iterates over everything not
nil
, without stopping. - Not allowing
nil
in the sequential table to begin with. Try table.remove