Check whether table contains nil

I need to check whether any mixed table contains nil

 -- for example 
 local tab = {1, nil, ["str"] = true}

pairs can’t be used to iterate through nil (and perform any operation for it, though it can get past it) nor can’t ipairs, so what’s the solution, to see whether a table contains a nil value (not associated with a key, but rather a value itself as a part of a mixed table).

For a table with a known amount of indices, I could do

 -- but this won't work with dictionaries
 for i = 1, indices do
     if tab[i] == nil then return "nil encountered" end 
 end

The # operator doesn’t count nil unless in specific cases, and there’s effectively no way to find out how many elements are in a table like above (as far as my knowledge goes).

There isn’t anything I can think of other than somehow involve metamethods, except.

table.find() is not relevant to dictionaries (along with any function from the table library), and cannot to be used to do this either.

Could you clarify a bit as what you’re trying to achieve?

nil can be translated to mean nothing. So theoretically, you can’t count nil values in your table, as literally nil means nothing.

However, you can determine if a key has a nil value pair.

1 Like

Could you explain your use case for this? A table can’t “contain nil”, that makes no sense.

1 Like

Mixed tables are tables that have both integer keys from 1…n, and other named keys, as a way to reference those entities.

At the very least, its common for tables that are valid sequences (“lists”) to have some administriva attached to them in regular records.

lets get one thing clear, other languages separate sequences (arrays, lists, vectors, etc) and dictionaries (hashmaps, keymaps, recordsets, etc) into seperate types.
lua does not. we don’t care, and we mix the concepts whenever we feel like it, for whatever reason we choose.

some uses of tables are idiomatic enough to have names or associated syntax – like “sequences” – but theres nothing special about these things. The end result is just a regular table.

— Parceni

1 Like

I do not have a use case for this other than for attempting to solve another thread, I just simply want to know whether a table contains nil literally, without knowing the amount of total indices that exist within it.

local tab = {1, ["key"] = "value", nil}
-- I just want to see whether that nil exists at the end, but without knowing how many indices exist
-- and it has to work with dictionaries, so can't use a numeric loop

Technically the nil isn’t even there.

for _,v in pairs(tab) do
    if v == nil then
        print("NIL I'm NIL")
    end
end
1 Like

That doesn’t even work, the nil is not even there.

1 Like

Technically only, but if it isn’t there then…

local tab = { nil, 2, nil, nil, 5}
print(#tab)

prints 5, is there some way to just remove all the nil values without knowing their existence??

print(#{nil,nil}) -- > prints 0

what is this behavior of nil, can anyone clarify?
I found a post like this recently in stackoverflow, but I lost that one.

For tables with holes the behavior of the length operator is undefined.

For this reason I recommend using table.pack to construct your arrays.

local t = table.pack(nil, nil, true, nil, nil, true, nil)
print(t.n) -- 7
print(#{ nil, nil, true, nil, nil, true, nil }) -- 3
1 Like

make a new table and inserts the children?

local tab = {"hello",nil,"there"}

print(#tab) --prints 3

local filteredtab = {}

for _,v in pairs(tab) do
	table.insert(filteredtab,v)
end

print(#filteredtab) --prints 2
1 Like

That’s alright for filtering nil out, but the thing is, I need to know how many total indices exist as well, but that’s not possible with # because the behavior is undefined, I need to consider nil as well because it’s guaranteed to be in the table, on top of dictionary keys which can be counted through pairs.

I’m assuming he is referring to holes within the table(s)

2 Likes

you can just minus the #tab and #filteredtab to see how many nils exist?

idk what u mean sorry

and do some math

2 Likes

I don’t really know why I didn’t consider that, I was over-complicating things.

Haven’t slept


local tab = { 4, nil, 3, ["a"] =  b}

local i = 0

for _, _ in pairs(tab) do
    i = i + 1 -- this isn't Luau btw
end

if i - #tab ~= 0 then print("nil exists") end

Edit: Thank you, but I already got what I wanted.

The thread I was talking about before was this:

1 Like

i made a weird filter function, not for you to use, but maybe it will give u some ideas, sorry!

local tab = {"hello",nil,"there",nil,nil,"hello world"}


function getallindexfornils(giventable)
	local filteredtable = {}
	for i,_ in pairs(giventable) do
		table.insert(filteredtable,i)
	end
	local niltable = {}
	for i = 1,#giventable,1 do
		if not table.find(filteredtable,i) then
			table.insert(niltable,i)
		end
	end
	return niltable
end

local indexthatarenils = getallindexfornils(tab)

for _,v in pairs(indexthatarenils) do
	print(v.. " is nil.")
end

Output

Screenshot_9

2 Likes

Or you could simply use table.pack:

function detectNil (…)

local arg = table.pack(…)
for i = 1, arg.n do
if arg[i] == nil then return false end
end
return true
end

print(detectNil(1,4,5))
— Test it out and enjoy

1 Like