This question already has answers here:
Why does Lua's length (#) operator return unexpected values?
(2 answers)
Closed 6 years ago.
I am new to lua and my lua version is 5.1.
I've got this problem. Can anybody help me to explain '#'?
local tblTest =
{
[1] = 2,
[2] = 5,
[5] = 10,
}
print(#tblTest)
this output 2 and ..
local tblTest =
{
[1] = 2,
[2] = 5,
[4] = 10,
}
print(#tblTest)
output is 4. Why?
thanks all of u.
The output is 4 because the last key with a value is 4 but that doesn't mean that 3 isn't also defined. In lua 3 would be defined as nil. So when you use the # operator it counts every key in a sequence with a value until the last non-nil value. Except,(and I could be wrong about this) the last key in the table is a power of 2, which do to language optimization, it counts up to the value that is a power of 2. In general you should stay away from tables with nil values as there are some other weird behaviors that happen because of this.
This chunk with do what you want though:
local T = {
[1] = 2,
[2] = 5,
[10] = 10
}
local lengthNum = 0
For k, v in pairs(T) do -- for every key in the table with a corresponding non-nil value
lengthNum = lengthNum + 1
end
print(lengthNum)
}
What this does is it checks the entire table for keys (such as [1] or [2]) and checks if they have value. Every key with a non-nil value runs the for loop one more time. There might be a shorter way to this, but this is how I would do it.
Related
I have trouble understanding the code of this recursive function. I am new to DART programming. I understand what a recursive function accomplishes, but I have a problem understanding the programming syntax.
int sum(List<int> numberList, int index) {
if (index < 0) {
return 0;
} else {
return numberList[index] + sum(numberList, index - 1);
}
}
main() {
// Driver Code
var result = sum([1, 2, 3, 4, 5], 4);
print(result);
}
Question: where is the value for each step stored- Does the result for the first pass at line 5 equals 9 taken the inputs from line 11. Where is the value of result 9 stored? How does the function know to add 9 + 3 in the second pass?
Does the recursive function have "internal memory" of the values generated by each pass?
My understanding of the programing language would be that var result passes the arguments to the sum function.
The sum function executes the if-else command until the index value is 0, which means it executes 4 times. With the first pass the return command creates a value of 9 (5 + 4 since value of index is 5 and value of index-1 is 4).
Here begins my confusion. The sum function would now do a second if-else pass and execute the return command again.
Now the initial value of numberList[index] would need to be 9 and the value of sum(numberList, index - 1); would need to be 3, to get 9 + 3 = 12. Additional 2 passes gets 12 + 2 = 14 and 14 + 1 = 15 the expected result.
My question here is how does (if it does) the index value in the "numberList[index]" changes. The index value is defined as 4. Is this an internal logic of the recursive function or am I completely misinterpreting the programming syntax? I would expect that we have a "temporary" variable for the result which increases with each pass.
Why lua table (rehashes?) avoid gaps when I use different syntax?
inspect function
d = require "core/modules/inspect"
Case1: standart syntax 1st element is a gap
t = {1,2,3}
t[1] = nil
d(t)
__________
{ nil, 2, 3 }
Case2: with brackets syntax is no gaps
t = {
[1] = 1,
[2] = 2,
[3] = 3,
}
t[2] = nil
d(t)
__________
{ 1,
[3] = 3
}
Case3: dynamic array - no gaps
t = {}
t[1] = 1
t[2] = 2
t[3] = 3
t[2] = nil
d(t)
__________
{ 1,
[3] = 3
}
Case4: dynamic array when set nil in 1st element - is a gap
t = {}
t[1] = 1
t[2] = 2
t[3] = 3
t[1] = nil
d(t)
__________
{ nil, 2, 3 }
Case5: with brackets syntax set nil in 1st element is still no gaps
t = {
[1] = 1,
[2] = 2,
[3] = 3,
}
t[1] = nil
d(t)
__________
{
[2] = 2,
[3] = 3
}
Lua does not define behaviour for the length operator for non-sequential indexes, but the accepted answer to Why does Lua's length (#) operator return unexpected values? goes into what practically happens in the standard implementation of Lua 5.2. That said, that answer on its own doesn't completely explain the behaviour, so here's a case-by-case explanation, using Lua 5.3.5's standard implementation.
Note: I use the length operator to clearly show cases where holes are occuring. Regarding how this applies to the inspection function you've used, from what I can see of its behaviour it simply explicitly states any indexes outside of the range 1 <= index <= #table.
Case 1:
> t = {1,2,3}
> t[1] = nil
> print(#t)
3
The size of a Lua table's array part is based on a power of two - except when a table is constructed with pre-set values. The line t = {1,2,3} creates a table with an array part of size 3. When you perform t[1] = nil, the array part has no reason to re-size, so its size remains at 3. As the last item in the array part is non-nil, and the hash part is empty, the array size - 3 - is returned.
Case 2:
> t = {[1] = 1, [2] = 2, [3] = 3}
> t[2] = nil
> print(#t)
1
If you're defining table values within the table constructor, Lua will associate any key within square brackets with the hash part of the table. So, the array part of the table is actually empty. The implementation performs a binary search on the hash part of the array, and gets 1.
Case 3:
> t = {}
> t[1] = 1
> t[2] = 2
> t[3] = 3
> t[2] = nil
> print(#t)
1
When square brackets are used outside of the constructor, Lua will check numerical indexes to see if they should go into the array part or the hash part. In this case, each of the indexes will go into the array part, but because these values are defined outside of the constructor, the array will be sized on assignment based on powers of two. So, after the initial three assignments the array part will have a size of 4. The nil assignment doesn't trigger a re-size, so it stays at 4. Thus, when the length operator is applied, it sees that the final value in the array's space is nil, and so it binary searches for the index before the first nil value, which is 1.
Case 4:
> t = {}
> t[1] = 1
> t[2] = 2
> t[3] = 3
> t[1] = nil
> print(#t)
3
This case is exactly the same case Case 3, but the binary search sees that t[2] is non-nil and so doesn't consider the values at any index before 2. This results in the search continuing on the indexes after 2, which concludes that the length is 3.
Case 5:
> t = {[1] = 1, [2] = 2, [3] = 3}
> t[1] = nil
> print(#t)
0
This is like Case 2 in the sense that the table items are members of the hash part of the table. In this case, however, the search process results in 0. This is because before attempting the binary search, the function determines what range of integer indexes it should search over. The presence of a nil value at the first index means that the loop which determines the range doesn't run. For more information on how that search process works, you can see the function here. When I say the loop doesn't run, I am specifically referring to the while condition, !ttisnil(luaH_getint(t, j)).
Bonus case:
> t = {}
> t[1] = 1
> t[4] = 4
> print(#t)
1
> g = {}
> g[1] = 1
> g[3] = 3
> g[4] = 4
> print(#g)
4
In Case 3 I mentioned the fact that Lua decides whether to put a numerical index in the array part or the hash part. In the composition of the table t above, index 1 is in the array part and 4 in the hash part. As such, the length returned is 1. In the case of g, all values are placed into the array part. This is because when assigning values to indexes, Lua tries to re-size the array part in an optimal way. For a greater understanding of this re-sizing process, you can view the source here.
I'm attempting to use a table as a means to do two things at once. For example:
s = passengers -- user input
t = {[3] = car, [7] = bus, [24] = plane, [45] = train}
for k,v in ipairs t do
if s = k then
z = v * 10 -- cost per person
end
end
Now this is extremely basic for what I'm trying to do. I have a list of about 12 items that each have their own number. I want to know if I can do what I did above with the table and provide each of the 12 items with their own key value and then use that ? This key value would represent each items particular, unique number. Also, can I then use that key's value in a later equation, such as above?
If your keys are unique, your data structure. The point of a table key is direct access to the corresponding value.
This has the same effect as your loop:
local v = t[s] -- value for s or nil if s is not a key
if v != nil then
z = v * 10
end
(Or, more exactly the same: local v = rawget(t,s) to account for cases where t has an __index metamethod.)
If we can assume that v will never be false (which would cause an error at false * 10) then it can be written more naturally (which skips that error):
local v = t[s]
if v then
z = v * 10
end
I am starting to learn Lua from Programming in Lua (2nd edition)
I didn't understand the following in the book. Its very vaguely explained.
a.) w={x=0,y=0,label="console"}
b.) x={math.sin(0),math.sin(1),math.sin(2)}
c.) w[1]="another field"
d.) x.f=w
e.) print (w["x"])
f.) print (w[1])
g.) print x.f[1]
When I do print(w[1]) after a.), why doesn't it print x=0
What does c.) do?
What is the difference between e.) and print (w.x)?
What is the role of b.) and g.)?
You have to realize that this:
t = {3, 4, "eggplant"}
is the same as this:
t = {}
t[1] = 3
t[2] = 4
t[3] = "eggplant"
And that this:
t = {x = 0, y = 2}
is the same as this:
t = {}
t["x"] = 0
t["y"] = 2
Or this:
t = {}
t.x = 0
t.y = 2
In Lua, tables are not just lists, they are associative arrays.
When you print w[1], then what really matters is line c.) In fact, w[1] is not defined at all until line c.).
There is no difference between e.) and print (w.x).
b.) creates a new table named x which is separate from w.
d.) places a reference to w inside of x. (NOTE: It does not actually make a copy of w, just a reference. If you've ever worked with pointers, it's similar.)
g.) Can be broken up in two parts. First we get x.f which is just another way to refer to w because of line d.). Then we look up the first element of that table, which is "another field" because of line c.)
There's another way of creating keys in in-line table declarations.
x = {["1st key has spaces!"] = 1}
The advantage here is that you can have keys with spaces and any extended ASCII character.
In fact, a key can be literally anything, even an instanced object.
function Example()
--example function
end
x = {[Example] = "A function."}
Any variable or value or data can go into the square brackets to work as a key. The same goes with the value.
Practically, this can replace features like the in keyword in python, as you can index the table by values to check if they are there.
Getting a value at an undefined part of the table will not cause an error. It will just give you nil. The same goes for using undefined variables.
local w = {
--[1] = "another field"; -- will be set this value
--["1"] = nil; -- not save to this place, different with some other language
x = 0;
y = 0;
label = "console";
}
local x = {
math.sin(0);
math.sin(1);
math.sin(2);
}
w[1] = "another field" --
x.f = w
print (w["x"])
-- because x.f = w
-- x.f and w point one talbe address
-- so value of (x.f)[1] and w[1] and x.f[1] is equal
print (w[1])
print ((x.f)[1])
print (x.f[1])
-- print (x.f)[1] this not follows lua syntax
-- only a function's has one param and type of is a string
-- you can use print "xxxx"
-- so you print x.f[1] will occuur error
-- in table you can use any lua internal type 's value to be a key
-- just like
local t_key = {v=123}
local f_key = function () print("f123") end
local t = {}
t[t_key] = 1
t[f_key] = 2
-- then t' key actualy like use t_key/f_key 's handle
-- when you user t[{}] = 123,
-- value 123 related to this no name table {} 's handle
Okay, so I've got a strange problem with the following Lua code:
function quantizeNumber(i, step)
local d = i / step
d = round(d, 0)
return d*step
end
bar = {1, 2, 3, 4, 5}
local objects = {}
local foo = #bar * 3
for i=1, #foo do
objects[i] = bar[quantizeNumber(i, 3)]
end
print(#fontObjects)
After this code has been run, the length of objects should be 15, right? But no, it's 4. How is this working and what am I missing?
Thanks, Elliot Bonneville.
Yes it is 4.
From the Lua reference manual:
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero. For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value. If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).
Let's modify the code to see what is in the table:
local objects = {}
local foo = #bar * 3
for i=1, foo do
objects[i] = bar[quantizeNumber(i, 3)]
print("At " .. i .. " the value is " .. (objects[i] and objects[i] or "nil"))
end
print(objects)
print(#objects)
When you run this you see that objects[4] is 3 but objects[5] is nil. Here is the output:
$ lua quantize.lua
At 1 the value is nil
At 2 the value is 3
At 3 the value is 3
At 4 the value is 3
At 5 the value is nil
At 6 the value is nil
At 7 the value is nil
At 8 the value is nil
At 9 the value is nil
At 10 the value is nil
At 11 the value is nil
At 12 the value is nil
At 13 the value is nil
At 14 the value is nil
At 15 the value is nil
table: 0x1001065f0
4
It is true that you filled in 15 slots of the table. However the # operator on tables, as defined by the reference manual, does not care about this. It simply looks for an index where the value is not nil, and whose following index is nil.
In this case, the index that satisfies this condition is 4.
That is why the answer is 4. It's just the way Lua is.
The nil can be seen as representing the end of an array. It's kind of like in C how a zero byte in the middle of a character array is actually the end of a string and the "string" is only those characters before it.
If your intent was to produce the table 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5 then you will need to rewrite your quantize function as follows:
function quantizeNumber(i, step)
return math.ceil(i / step)
end
The function quantizeNumber is wrong. The function you're looking for is math.fmod:
objects[i] = bar[math.fmod(i, 3)]