Lua key name starts with digit in table statement - lua

When key name starts with digit, in javascript we can define array-like object like this:
var table = {
'123.com': 'details'
'456.net': 'info'
}
But when I try these code in Lua5.1:
table = { '123.com' = 'info' }
It throws an error:
[string "local"]:1: '}' expected near '='
But these code are accepted in lua:
table = {}
table['123.com'] = 'info'
I wonder if it is a bug in Lua5.1. Or did I missed something?

When creating a Lua table using the literal table constructor, non-identifier table indices should be enclosed in square brackets. For example:
table = { ['123.com'] = 'info' }
(From: http://www.lua.org/pil/3.6.html)

Related

lua table constructor with keys containing spaces

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"]

Nested forEach, How to distinguish between inner and outer loop parameters?

In Kotlin, if you want to use the element of the forEach, you can use the it keyword. So now I wonder that what should I do if I have a forEach inside forEach like that:
list.forEach {
val parent = it
it.forEach {
// `it` now become the element of the parent.
}
}
I think that defines a new variable only for the naming convention be so stupid. Have any other solution for this problem?
it is just a default param name inside of all single argument closures. You could specify param name by yourself:
collection.forEach { customName ->
...
}
In addition to the correct answer above by Artyom, I'd like to say that if you only care for the inner it, you can simply ignore the name overloading.
See:
>> var a = "abc"
>> a?.let { it[2]?.let { it } }
c
The value returned is the most inner "it". "it", there, refers to the outermost "it[2]", that is, the character 'c' from the string "abc".
Now, if you want to access the outermost "it", you should name it something else like Artyom says. The code below is equivalent to the code above, but it allows you to refer to "outerIt" from the outer 'let' block in the innermost 'let' block, if that's what you need.
>> var a = "abc"
>> a?.let { outerIt -> outerIt[2]?.let { it } }
c
This way, if you need to refer to the outermost it, you can. For example:
>> var a = "abc"
>> a?.let { outerIt -> outerIt[2]?.let { "${outerIt[1]} $it" } }
b c
If you don't need to refer to the outermost "it", I'd personally prefer the first construct because it is terser.

Table in Table with custom key name

I have to declare a table in a table that will act like this:
table = {'79402d' = {'-5.4','5','1.6'}, '5813g1' = {'3','0.15','18'}}
So when I loop through it, I can use something similar to table['79402d'][0] to print coordinates.
There are two types of syntax for table constructors. The general form:
t = { ['key'] = value }
(If the key is a valid identifier)The syntax sugar form:
t = { key = value }
Here you are mixing them up. Because 79402d isn't a valid identifier (beginning with letters or underscore), you have to use the general form:
t = {['79402d'] = {'-5.4','5','1.6'}, ['5813g1'] = {'3','0.15','18'}}

Inserting Key Pairs into Lua table

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.

Lua: implicit table creation with string keys - why the extra brackets?

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
}

Resources