Reputation: 3157
I have such an anonymous Lua function:
an_func = function(x) return x == nil end
I need to test it on a table from 4 values: {'None', nil, 1, '1'}
.
So, I wrote the following code:
for num, element in pairs({'None', nil, 1, '1'}) do
print(num .. ': ' .. tostring(an_func(element)))
end
When I ran it, I got only three lines:
1: false
3: false
4: false
The line with the true
value (corresponding to nil
table element) didn't print.
Can you explain, why did Lua print all results, but true
? How can I fix the snipped make it output all 4 lines?
P.S. I'm newbee in Lua.
Upvotes: 3
Views: 5697
Reputation: 20772
Other answers address your second question well but the simple explanatory facts are Any key with value nil
is not considered part of the table. Conversely, any key that is not part of a table has an associated value nil
. Assigning a value of nil
removes any existing key-value pair with the same key.
Upvotes: 3
Reputation: 3113
In Lua, everything (a function, string, thread, ...) is a value, with nil
(and technically none/void) being the only exception(s). To put simply, nil
represents the absence of value. So when iterating over a table, why would Lua say there is nothing there. If it did it would have to iterate over every virtually possible index you can create.
However it appears you are using an array. You technically can iterate over it assuming you know the length. I'll make the assumption that the last item in the table is NOT nil
, and that there wasn't any holes assigned after the initial length of the table with holes, however this may not necessarily be true in your case, if it isn't you will have to keep track of the length yourself and use it rather than the # operator:
for i = 1,#t do
local v = t[i]
print (v == nil)
end
Upvotes: 4
Reputation: 1156
You would need to loop through all keys you want to print the values for. Possible ways:
Each has their good and bad sides, here are some:
For the first you would need to know the length beforehand in all cases which may be difficult. The end marker is convenient, but requires you to shift around the end marker. Calculating length would not work if the last element is nil.
Example of calculating the length - assuming last element is not nil. Note that lua 5.1 has table.maxn that you can use instead of this custom implementation of maxn.
an_func = function(x) return x == nil end
function maxn(t)
local n = 0
for k,v in pairs(t) do
if k%1 == 0 then
n = k
end
end
return n
end
local t = {'None', nil, 1, '1'}
for num = 1, maxn(t) do
print(num .. ': ' .. tostring(an_func(t[num])))
end
Example of using an end marker:
an_func = function(x) return x == nil end
local END = {}
local t = {'None', nil, 1, '1', END}
local num = 1
while t[num] ~= END do
print(num .. ': ' .. tostring(an_func(t[num])))
num = num+1
end
Upvotes: 1
Reputation: 755
When using pairs(), it goes over all elements of a table. nil means nothing, so it won't go over it. Why should it tell you there's nothing in the table? If you have a totally new table, it'll return nil if you index it with anything. print(({}).test) --> nil
If you really want to get the nil, you could use a dummy value:
local NIL = setmetatable({},{__tostring=function() return "nil" end})
an_func = function(x) return x == NIL end
for num, element in pairs({'None', NIL, 1, '1'}) do
print(num .. ': ' .. tostring(an_func(element)))
end
Output:
1: false
2: true
3: false
4: false
Upvotes: 9