Lua is a highly versatile programming language. It is widely used in gaming, embedded systems, web development, networking, automation, and customization. Its small size, flexibility, and speed make it a great choice for embedding into larger applications or for use in environments with constrained resources. When using Lua, we can’t avoid tables. Lua tables are flexible and can be used as arrays, dictionaries (hash maps), or even mixed structures. Tables have no fixed size and can grow based on our needs. Meanwhile, there is one important thing we should not forget: ordering in tables. Order insertion in tables Lua tables, when used as arrays, maintain the insertion order, which makes them a good candidate for lists or arrays in various use cases, including with Redis. In this case, tables can be created manually in the script or returned as a result by third-party libraries, like Redis. Let’s create the table manually and check the insertion order: steps = {} for i = 1, 10, 1 do table.insert(steps,i) end After the loop, steps = {1; 2; 3; 4; 5; 6; 7; 8; 9; 10} Let’s check what happens when Redis returns a table as a result. redis.call("HSET", 'users', 345, "John", 122, "Bob", 543, "Sam") local dataDb = redis.call("HGETALL", 'users') After the script is executed, dataDb = {"345", "John", "122", "Bob", "543", "Sam"} In both scenarios, we can find the created table as an array where the insertion order is preserved. But what if we need to convert the Redis response (which is a table as an array) into a key-value associative array? For the first example, we store the following key-value pairs in Redis and want to use the same structure in Lua when processing: { 345: {name: “John”}, 122: {name: “Bob”}, 543: {name: “Sam”}, 202: {name: “Peter”} } Run the following script and check the created associative array: redis.call("HSET", 'users', 345, "John", 122, "Bob", 543, "Sam", 202, "Peter") local dataDb = redis.call("HGETALL", 'users') local directory = {} for i = 1, #dataDb, 2 do directory[dataDb[i]] = dataDb[i+1] end where, after the loop dataDb = {"345"; "John"; "122"; "Bob"; "543"; "Sam"; "202"; "Peter"} directory = {["122"]="Bob"; ["345"]="John"; ["202"]="Peter"; ["543"]="Sam"} Let's look at another example of using the cjson module: redis.call('SET', 'packages', '{"10":{"name":"Plus"},"15":{"name":"Family"},"25":{"name":"Premium"}}') local pkgsDb = redis.call('GET', 'packages') local parsedPkgs = cjson.decode(pkgsDb) where: pkgsDb = "{\"10\":{\"name\":\"Plus\"},\"15\":{\"name\":\"Family\"},\"25\":{\"name\":\"Premium\"}}" parsedPkgs = {["25"]={["name"]="Premium"}; ["15"]={["name"]="Family"}; ["10"]={["name"]="Plus"}} It is good to remember that the CJSON module returns a table in a different order than the one parsed in the JSON. This can prevent errors and save you time, as debugging such problems is quite difficult. In both scenarios, we may find that the insertion order is not guaranteed in a table as an associative array. How to sort a table key when needed? Sometimes, having ordered tables in Lua is important. The order of elements can be critical for the functionality that the script provides. We can use the built-in table.sort function to sort tables. It receives the array to be sorted, along with an optional order function. If this function is not provided, sort uses the default mode. All numeric values will be sorted in ascending order, and all strings will be sorted alphabetically. Sorting table – array In the case of simple sorting of numeric or string values, it is enough to use the following expression: local num = {4, 2, 6} local str = {"pear" ,"apple", "melon"} table.sort(num) table.sort(str) where sorted num = {2; 4; 6} and str = {"apple"; "melon"; "pear"} If the sorting is based on a certain condition, we can define a comparison function. local t = {4,7,2,3} table.sort(t, function(a, b) return a > b end) where sorted t = {4; 7; 2; 3} Sorting a table – dictionary To sort a table structured as a dictionary, we can sort it by key or value. This requires several steps: Extract the keys or values into an array-like table Sort this array Iterate over the sorted keys and get the value from the original array by key Sort by keys: local transport = {[100]="train", [70]="tram", [90]="bus"} local keys = {} for key in pairs(transport) do table.insert(keys, key) end table.sort(keys) for _, key in ipairs(keys) do print(key, transport[key]) end Script result: 70 tram, 90 bus, 100 train Sort by values: local entities = {} for key, value in pairs(transport) do table.insert(entities, {key = key, value = value}) end table.sort(entities, function(a, b) return a.value < b.value end) for _, entity in ipairs(entities) do print(entity.key, entity.value) end Script result: 90 bus, 100 train, 70 tram Conclusion Having ordered tables in Lua is important when the order of elements matters. In Lua, tables that function like dictionaries have no inherent order, meaning that when we iterate over them using pairs(), the order of elements is not guaranteed. In this article, we explored how to sort arrays in Lua using table.sort and how to manage separate key and value arrays for sorting dictionaries. Lua is a highly versatile programming language. It is widely used in gaming, embedded systems, web development, networking, automation, and customization. Its small size, flexibility, and speed make it a great choice for embedding into larger applications or for use in environments with constrained resources. When using Lua, we can’t avoid tables. Lua tables are flexible and can be used as arrays, dictionaries (hash maps), or even mixed structures. Tables have no fixed size and can grow based on our needs. Meanwhile, there is one important thing we should not forget: ordering in tables . ordering in tables Order insertion in tables Order insertion in tables Lua tables, when used as arrays, maintain the insertion order, which makes them a good candidate for lists or arrays in various use cases, including with Redis . Redis In this case, tables can be created manually in the script or returned as a result by third-party libraries, like Redis. Let’s create the table manually and check the insertion order: steps = {} for i = 1, 10, 1 do table.insert(steps,i) end steps = {} for i = 1, 10, 1 do table.insert(steps,i) end After the loop, steps = {1; 2; 3; 4; 5; 6; 7; 8; 9; 10} After the loop, steps = {1; 2; 3; 4; 5; 6; 7; 8; 9; 10} Let’s check what happens when Redis returns a table as a result. redis.call("HSET", 'users', 345, "John", 122, "Bob", 543, "Sam") local dataDb = redis.call("HGETALL", 'users') redis.call("HSET", 'users', 345, "John", 122, "Bob", 543, "Sam") local dataDb = redis.call("HGETALL", 'users') After the script is executed, dataDb = {"345", "John", "122", "Bob", "543", "Sam"} After the script is executed, dataDb = {"345", "John", "122", "Bob", "543", "Sam"} In both scenarios, we can find the created table as an array where the insertion order is preserved. In both scenarios, we can find the created table as an array where the insertion order is preserved. But what if we need to convert the Redis response (which is a table as an array) into a key-value associative array? For the first example, we store the following key-value pairs in Redis and want to use the same structure in Lua when processing: { 345: {name: “John”}, 122: {name: “Bob”}, 543: {name: “Sam”}, 202: {name: “Peter”} } { 345: {name: “John”}, 122: {name: “Bob”}, 543: {name: “Sam”}, 202: {name: “Peter”} } Run the following script and check the created associative array: redis.call("HSET", 'users', 345, "John", 122, "Bob", 543, "Sam", 202, "Peter") local dataDb = redis.call("HGETALL", 'users') local directory = {} for i = 1, #dataDb, 2 do directory[dataDb[i]] = dataDb[i+1] end redis.call("HSET", 'users', 345, "John", 122, "Bob", 543, "Sam", 202, "Peter") local dataDb = redis.call("HGETALL", 'users') local directory = {} for i = 1, #dataDb, 2 do directory[dataDb[i]] = dataDb[i+1] end where, after the loop where, after the loop dataDb = {"345"; "John"; "122"; "Bob"; "543"; "Sam"; "202"; "Peter"} dataDb = {"345"; "John"; "122"; "Bob"; "543"; "Sam"; "202"; "Peter"} directory = {["122"]="Bob"; ["345"]="John"; ["202"]="Peter"; ["543"]="Sam"} directory = {["122"]="Bob"; ["345"]="John"; ["202"]="Peter"; ["543"]="Sam"} Let's look at another example of using the cjson module: redis.call('SET', 'packages', '{"10":{"name":"Plus"},"15":{"name":"Family"},"25":{"name":"Premium"}}') local pkgsDb = redis.call('GET', 'packages') local parsedPkgs = cjson.decode(pkgsDb) redis.call('SET', 'packages', '{"10":{"name":"Plus"},"15":{"name":"Family"},"25":{"name":"Premium"}}') local pkgsDb = redis.call('GET', 'packages') local parsedPkgs = cjson.decode(pkgsDb) where: where: pkgsDb = "{\"10\":{\"name\":\"Plus\"},\"15\":{\"name\":\"Family\"},\"25\":{\"name\":\"Premium\"}}" pkgsDb = "{\"10\":{\"name\":\"Plus\"},\"15\":{\"name\":\"Family\"},\"25\":{\"name\":\"Premium\"}}" parsedPkgs = {["25"]={["name"]="Premium"}; ["15"]={["name"]="Family"}; ["10"]={["name"]="Plus"}} parsedPkgs = {["25"]={["name"]="Premium"}; ["15"]={["name"]="Family"}; ["10"]={["name"]="Plus"}} It is good to remember that the CJSON module returns a table in a different order than the one parsed in the JSON. This can prevent errors and save you time, as debugging such problems is quite difficult. It is good to remember that the CJSON module returns a table in a different order than the one parsed in the JSON. This can prevent errors and save you time, as debugging such problems is quite difficult. In both scenarios, we may find that the insertion order is not guaranteed in a table as an associative array. In both scenarios, we may find that the insertion order is not guaranteed in a table as an associative array. How to sort a table key when needed? How to sort a table key when needed? Sometimes, having ordered tables in Lua is important. The order of elements can be critical for the functionality that the script provides. We can use the built-in table.sort function to sort tables. It receives the array to be sorted, along with an optional order function. If this function is not provided, sort uses the default mode. All numeric values will be sorted in ascending order, and all strings will be sorted alphabetically. table.sort Sorting table – array Sorting table – array In the case of simple sorting of numeric or string values, it is enough to use the following expression: In the case of simple sorting of numeric or string values, it is enough to use the following expression: local num = {4, 2, 6} local str = {"pear" ,"apple", "melon"} table.sort(num) table.sort(str) local num = {4, 2, 6} local str = {"pear" ,"apple", "melon"} table.sort(num) table.sort(str) where sorted num = {2; 4; 6} and str = {"apple"; "melon"; "pear"} where sorted num = {2; 4; 6} and str = {"apple"; "melon"; "pear"} If the sorting is based on a certain condition, we can define a comparison function. local t = {4,7,2,3} table.sort(t, function(a, b) return a > b end) local t = {4,7,2,3} table.sort(t, function(a, b) return a > b end) where sorted t = {4; 7; 2; 3} where sorted t = {4; 7; 2; 3} Sorting a table – dictionary Sorting a table – dictionary To sort a table structured as a dictionary, we can sort it by key or value. This requires several steps: Extract the keys or values into an array-like table Sort this array Iterate over the sorted keys and get the value from the original array by key Extract the keys or values into an array-like table Extract the keys or values into an array-like table Sort this array Sort this array Iterate over the sorted keys and get the value from the original array by key Iterate over the sorted keys and get the value from the original array by key Sort by keys: Sort by keys: local transport = {[100]="train", [70]="tram", [90]="bus"} local keys = {} for key in pairs(transport) do table.insert(keys, key) end table.sort(keys) for _, key in ipairs(keys) do print(key, transport[key]) end local transport = {[100]="train", [70]="tram", [90]="bus"} local keys = {} for key in pairs(transport) do table.insert(keys, key) end table.sort(keys) for _, key in ipairs(keys) do print(key, transport[key]) end Script result: 70 tram, 90 bus, 100 train Script result: 70 tram, 90 bus, 100 train Sort by values: Sort by values: local entities = {} for key, value in pairs(transport) do table.insert(entities, {key = key, value = value}) end table.sort(entities, function(a, b) return a.value < b.value end) for _, entity in ipairs(entities) do print(entity.key, entity.value) end local entities = {} for key, value in pairs(transport) do table.insert(entities, {key = key, value = value}) end table.sort(entities, function(a, b) return a.value < b.value end) for _, entity in ipairs(entities) do print(entity.key, entity.value) end Script result: 90 bus, 100 train, 70 tram Script result: 90 bus, 100 train, 70 tram Conclusion Having ordered tables in Lua is important when the order of elements matters. In Lua, tables that function like dictionaries have no inherent order, meaning that when we iterate over them using pairs() , the order of elements is not guaranteed. In this article, we explored how to sort arrays in Lua using table.sort and how to manage separate key and value arrays for sorting dictionaries. pairs() table.sort