I am trying to wrap my head around how tables work in Lua, but it is very confusing.
I am pulling data out of an existing table of strings, with an index number for each string. However the numbers are not consecutive. So my data looks like this:
mytable[0] = "the first string"
mytable[5] = "the second string"
mytable[13] = "the third string"
mytable[29] = "the fourth string"
I want to take each of these strings, concatenate the index number onto them and output them all into a single new string, like this:
"0: the first string\n,
5: the second string\n
13: the third string\n
29: the fourth string"
If I access the data using pairs, then I get the items out of order, and it is very important that they remain in order.
If I access the data using ipairs, it doesn't work because there are gaps in the index numbers.
How would I go about getting the data from the table into a string, while keeping it all in order?
You can do what Cássio says about creating a new array, or (just in case you are interested on an alternative method) you also could do something like this:
<script src="//github.com/fengari-lua/fengari-web/releases/download/v0.1.4/fengari-web.js"></script>
<script type="application/lua">
local mytable = {}
local myvalues = ""
local mystring = ""
mytable[0] = "the first string"
mytable[5] = "the second string"
mytable[13] = "the third string"
mytable[29] = "the fourth string"
for i = 0, 29 do --or any "reasonable" limit you don't expect to reach, like maybe 99 in this case?
myvalues = mytable[i] or nil
if myvalues then
mystring = mystring .. i .. ": " .. myvalues .. "\n"
end
end
print(mystring)
</script>
Which in this case results in:
0: the first string
5: the second string
13: the third string
29: the fourth string
But you could easily format the resulting string as you want... A less canonical way to do it, but there it is just in case it helps.
EDIT: Added as a Lua "snippet" just for the sake of testing it (🙄🤞)
Related
i know i can construct tables like this:
local t= {
first = "value1",
second = "value2"
}
and i now i can use keys containing spaces like t["some key"] = "some value"
but is there a way to construct table like above with keys containing spaces?
I tried a few things, but i only goit errors
You can declare any expression as a key in a table constructor by putting it in brackets:
local t = {
["some key"] = "some value",
[234567 + 2] = "other value",
}
local t= {
first = "value1",
second = "value2"
}
Is syntactic sugar for
local t= {
["first"] = "value1",
["second"] = "value2"
}
This convenient syntax only works for names. Lua names may only consist of letters, numbers and underscore and they must not start with a number.
As a valid Lua identifer may not contain a space you cannot use the syntactic sugar. Hence the only way to do this is to use the full syntax
local t = {["hello world"] = 1}
This also applies to indexing that table field. So the only way is t["hello world"]
Anyone tell me why this doesn't work?
GET_TABLE {1=ID}
key = string.format("%q", GET_TABLE[1])
RETURN_TABLE[key] = "ss"
print(RETURN_TABLE[ID])
print(GET_TABLE[1])
First print result: nil. Second print result: ID
I want the first print result to be: ss
GET_TABLE {1=ID}
key = "ID"
RETURN_TABLE[key] = "ss"
print(RETURN_TABLE[ID])
print(GET_TABLE[1])
The above works fine so I assume its due to the string.format not working right?
The %q format token returns the input as an escaped and quoted Lua string. This means that given the input ID it will return "ID" (the double quotes being part of the string!) which is a different string. (Or, represented as Lua strings, the input is 'ID' and the return value is '"ID"'.)
You have therefore set the ID key while trying to retrieve the "ID" key (which presumably does not exist).
> x = 'ID'
> =x
ID
> =string.format('%q', x)
"ID"
> =#x
2
> =#string.format('%q', x)
4
Your code does not compile (you need [] around the index), and you should use the raw string of ID, not the "quoted" string:
GET_TABLE = {[1]=ID}
key = string.format("%s", GET_TABLE[1])
Note that I had to initialize ID and RETURN_TABLE objects to the following:
ID = 'ID'
RETURN_TABLE = {}
Stylistic note: you should only use all-caps names for constants, otherwise too many makes code hard to read
I was wondering whether it is possible to display tables in the console. Something like:
player[1] = {}
player[1].Name = { "Comp_uter15776", "maciozo" }
InputConsole("msg Player names are: " .. player[1].Name)
However, this is obviously wrong as I receive the error about it not being able to concatenate a table value. Is there a workaround for this?
Much thanks in advance!
To turn an array-like table into a string, use table.concat:
InputConsole("msg Player names are: " .. table.concat(player[1].Name, " "))
The second argument is the string placed between each element; it defaults to "".
to make life easier on yourself for this... i'd recommend naming elements in the inner tables as well. this makes the code above easier to read when you need to get at specific values in a table that are meaningful for some purpose.
-- this will return a new instance of a 'player' table each time you call it.
-- if you need to add or remove attributes, you only need to do it in one place.
function getPlayerTable()
return {FirstName = "", LastName = ""}
end
local players = {}
local player = getPlayerTable()
player.FirstName = "Comp_uter15776"
player.LastName = "maciozo"
table.insert(players, player)
... more code to add players ...
local specific_player = players[1]
local specific_playerName = specific_player.FirstName..
" ".. specific_player.LastName
InputConsole("msg Some message ".. specific_playerName)
Just picking upon Lua and trying to figure out how to construct tables.
I have done a search and found information on table.insert but all the examples I have found seem to assume I only want numeric indices while what I want to do is add key pairs.
So, I wonder if this is valid?
my_table = {}
my_table.insert(key = "Table Key", val = "Table Value")
This would be done in a loop and I need to be able to access the contents later in:
for k, v in pairs(my_table) do
...
end
Thanks
There are essentially two ways to create tables and fill them with data.
First is to create and fill the table at once using a table constructor. This is done like follows:
tab = {
keyone = "first value", -- this will be available as tab.keyone or tab["keyone"]
["keytwo"] = "second value", -- this uses the full syntax
}
When you do not know what values you want there beforehand, you can first create the table using {} and then fill it using the [] operator:
tab = {}
tab["somekey"] = "some value" -- these two lines ...
tab.somekey = "some value" -- ... are equivalent
Note that you can use the second (dot) syntax sugar only if the key is a string respecting the "identifier" rules - i.e. starts with a letter or underscore and contains only letters, numbers and underscore.
P.S.: Of course you can combine the two ways: create a table with the table constructor and then fill the rest using the [] operator:
tab = { type = 'list' }
tab.key1 = 'value one'
tab['key2'] = 'value two'
Appears this should be the answer:
my_table = {}
Key = "Table Key"
-- my_table.Key = "Table Value"
my_table[Key] = "Table Value"
Did the job for me.
Say that you want to create a Lua table, and all its keys are valid lua identifiers. Then you can use the key=value syntax:
local niceTable = { I=1, like=1, this=1, syntax=1 }
If however your strings are not "identifiable", then you have to use the ['key']=value syntax:
local operators = { ['*']="Why", ['+']="the", ['/']="brackets", ['?']='?' }
I'm a bit baffled about this. What are those brackets doing there? What do they mean?
They identify the contained string as a key in the resulting table. The first form, you could consider as equal to
local niceTable = {}
niceTable.I = 1;
niceTable.like = 1;
The second form is equal to
local operators = {}
operators['*'] = "Why";
operators['+'] = "The";
The difference is purely syntactic sugar, except where the first one uses identifiers, so it has to follow the identifier rules, such as doesn't start with a number and interpret-time constant, and the second form uses any old string, so it can be determined at runtime, for example, and a string that's not a legal identifier. However, the result is fundamentally the same. The need for the brackets is easily explained.
local var = 5;
local table = {
var = 5;
};
-- table.var = 5;
Here, var is the identifier, not the variable.
local table = {
[var] = 5;
};
-- table[5] = 5;
Here, var is the variable, not the identifier.
The normal syntax for indexing a table is t[val]. For string keys only, Lua provides an alternate syntax, where t.foo is exactly equivalent to t["foo"]. This is purely a syntactical convenience, so-called 'syntax sugar'. It doesn't add functionality, it just gives you a less cluttered syntax for using strings as named fields.
There are a lot of strings keys this won't work for:
t["hello_world"] => t.hello_world -- works
t["hello world"] => t.hello world -- oops, space in the string
t["5 * 3"] => t.5 * 3 -- oops
t['[10]'] => t.[10] -- oops
Basically it only works if the string key would be a valid identifier.
Again, tables are indexed via [], and in most cases you need to use them:
t = {
-- [key] = value
[10] = "ten", -- number key, string value
["print function"] = print, -- string key, function value
["sub table"] = {}, -- string key, table value
[print] = 111, -- function key, number value
["foo"] = 123, -- string key, number value
}
Only if you're using a string key which would work as a valid identifier (no spaces, contains only word characters, numbers, or underlines, and doesn't begin with a number) can you use the shortcut syntax. For the table above, that would be only 'foo':
t = {
-- [key] = value
[10] = "ten", -- number key, string value
["print function"] = print, -- string key, function value
["sub table"] = {}, -- string key, table value
[print] = 111, -- function key, number value
foo = 123, -- string key, number value
}