Garry's Mod Wiki

Revision Difference

Beginner_Tutorial_Tables#561176

<cat>Dev.GettingStarted</cat>⤶ <title>Coding - Tables</title>⤶ <cat>Dev.Lua</cat>⤶ <title>Concepts - Tables and Arrays</title>⤶ # What Are Tables? Tables are variables that allow you to store multiple values within them, like a container. Tables provide you with the ability to map **values** to specific **keys**, like how a dictionary maps definitions (the values) to specific words (the keys). Going off of the dictionary example, one can look up any word in any dictionary and get the definition of it in return, in the same way that one can look up a key in a table and retrieve the value stored *at*, or *on*, that key. Keep in mind that this is an extremely basic explanation, and there really is so much more to tables than what is described here. ## Keys As mentioned above, tables in Lua contain keys and values; keys are identifiers for values, and are known as the "index" of any entry. Entries in a table might also be called "key/value pairs." One could use keys in multiple ways. First, keys can be numeric and/or represent the order of things, i.e.: ```lua [1] [2] [3] [4] [5] -- and so on... ``` Keys can also be strings, such as: ```lua ["String1"] ["AnotherOne"] ["EvenMore"] -- and so on... ``` When used to represent the order of things, keys let a table function more like `list`, or even `array`, objects in other languages - the keys are numeric, and sequential (in order). When strings (or other types) are used as keys, tables can be used more like a `dictionary` or hash map object. The best part of all this is that tables in Lua are able to use both of these kinds of "modes" at the same time! It's not just numbers or strings that can be used as keys, however. According to the official Lua Users' Wiki, keys can be any type of variable, except for `nil`. More often than not, however, they are usually defined as either numbers or strings. There can only be one value for every key in a table - keys must be unique. The only way to store more than one value on a specific key is to use a new table as the value. (This is still technically only one value, though - the table counts as a single value, but can have other stuff stored inside of it. This table-inside-a-table scenario is called a "nested" table.) ## Values Values can be any data type - even other tables! ## Table creation example ```lua -- Here, we are creating an empty table using the "table constructor" ( {} ) emptyTable = {} -- We can create a table with predefined values: table1 = { [1] = "First", [2] = "Second", } -- (Remember to put a comma after every 'key = value' line.) -- We can also have Lua fill in numeric "order" values automatically: table1 = { "First", "Second" } -- table1 will then contain [1] = First, and [2] = Second. -- We can define string keys on our table in two different ways: -- First, the shorthand way: table1.SomeStringKey = "Hello!" -- or, the long way: table1["SomeStringKey"] = "Hello!" -- To verbally describe both of these methods, we could say that: -- "table1 AT SomeStringKey EQUALS Hello!" ``` ## Looping over a table There are a few ways to loop over all of the key/value pairs in a table. The method you use will depend on how the keys are arranged. If Lua filled in your numeric "order" keys automatically, like in the last example, you can use a for loop to loop through the table just fine. If there are any keys that were NOT defined as numeric "order" keys, i.e. string keys, OR if you defined a numeric key "out of order," you will have to use `pairs()` to loop over the table. `pairs` will loop over all of the values in the table, including the numeric/order keys AND the string (or other type) keys; in other languages, this is kind of like a `for each` loop. ```lua -- Let's redefine our table, using the automatic numeric/order key method: table1 = { "First", "Second", "Third" } -- Now, I will take the same table we just made, and define a string key on the table. table1.StringKey = "Fourth?" -- Before putting the StringKey in the table, we could have just used a forloop, since -- all of the keys were automatically defined as ordered numbers. -- However, since there is now a StringKey in the table, we need to use pairs() to loop -- over the table, since a forloop won't "get" the entry for the StringKey. -- Let's use a forloop to loop over the numeric values. -- The variable 'i' will act as our key, and we can get the corresponding value -- by referencing 'table1[i]': for i=1,#table1 do print( i .. " == " .. table1[i] ) end -- This should print: -- 1 == First -- 2 == Second -- 3 == Third -- ...now let's see what that looks like with pairs. for k,v in pairs( table1 ) do -- Inside the pairs loop! -- Let's print each key in the table, and its corresponding value. print( k .. " == " .. v ) end -- This should print: -- 1 == First -- 2 == Second -- 3 == Third -- StringKey == Fourth? ``` ## Usage of the table library The <page>table</page> library is a standard Lua library which provides functions to manipulate tables. In Garry's Mod there are several extra useful functions added to this library. These are some examples of functions defined in the `table` library. ### table.Merge ```lua -- We define a table full of fruits, Fruits = { "Apple", "Orange", "Banana", "Pineapple", } -- And a table full of veggies. Veggies = { "Pepper", "Tomato" } -- We will use the table.Merge function to merge values in 'Veggies' into the 'Fruits' table. table.Merge( Fruits, Veggies ) -- args: to, from -- When this runs: -- the "Pepper" value from the Veggies table will replace the "Apple" value in Fruits (key '1'), and: -- the "Tomato" value from the Veggies table will replace the "Orange" value in Fruits (key '2'). -- Let's print all of the new values in 'Fruits': print( table.concat(Fruits," ") ) -- This will output: -- Pepper Tomato Banana Pineapple ``` ### table.Add ```lua -- Again, we have our Fruits and Veggies tables. Fruits = { "Apple", "Orange" } Veggies = { "Pepper", "Tomato" } -- Add all the values in Veggies to the end of the Fruits table: table.Add(Fruits, Veggies) -- args: to, from print( table.concat(Fruits," ") ) -- This will output: -- Apple Orange Pepper Tomato ``` ### Other table functions You can refer to the library page for the `table` library to discover all of the `table` library's functions. ## Other functions Some other functions are also useful for tables, including, but not limited to: ### ipairs We went over the use of `pairs` in the *Looping over a table* section. `pairs` has a sister function called `ipairs` that does the exact same thing `pairs` does (loops over all the k/v pairs in a table), but for the numeric keys only. ```lua Names = { [2] = "John", [1] = "Mary", [4] = "Mark", [3] = "Den" } -- Use ipairs to loop through the key/value pairs with numeric keys, and print them out: for k,v in ipairs( Names ) do print( k.. " == " .. v ) end -- This should output: -- 1 == Mary -- 2 == John -- 3 == Den -- 4 == Mark ``` ### RandomPairs `RandomPairs` loops through a table, but in a random order. ```lua Names = { "John", "Mary", "Mark", "Den" } for k,v in RandomPairs(Names) do print( v ) end -- This will output the names, but in a random order each time. -- It could look like: -- Den -- Mary -- Mark -- John -- Or, it could look like: -- John -- Den -- Mary -- Mark -- And so on and so forth. ``` ### SortedPairs `SortedPairs` lets you loop over all the key/value pairs in table, but it sorts the **keys** alphabetically. This is most useful for tables with string keys. ```lua -- Declare our table with some non-alphabetical-order string keys: Names = { E = 5, B = 2, A = 1, D = 4, C = 3, } -- Loop through with SortedPairs this time, and do the standard printing of 'k == v' for k,v in SortedPairs(Names) do print( k .. " == " .. v ) end -- This should output: -- A == 1 -- B == 2 -- C == 3 -- D == 4 -- E == 5 -- Note how SortedPairs sorted the keys alphabetically. ```