String.len isn't working

I’ve come across a problem that was rather odd. I’m made a for loop that is supposed to remove any string values that have a length of more than 2 characters but it isn’t working. Here’s my loop:

local stringTable = {"a1", "a11", "a2", "a44", "a12"}

for _, stringValue in pairs(stringTable) do
	if string.len(stringValue) > 2 then
		print(stringValue) --only prints "a11" and "a44" 
		table.remove(stringTable, table.find(stringTable, table.find(stringTable, stringValue)))
	end
end

print(stringTable) --prints "a1", "a11", "a2"

Why might there still be strings longer than a length of 2 characters left in the table and why isnt “a12” being printed in the for loop aswell?

This should work:

for _, stringValue in pairs(stringTable) do
    if #table.pack(table.find(stringTable, stringValue)) > 1 then
        table.remove(stringTable, table.find(stringTable, stringValue)) 
    end
    if string.len(stringValue) > 2 then
        table.remove(stringTable, table.find(stringTable, stringValue)) 
    end
end

It might not answer your question, but you could try something like this instead:

local function addFilteredValue(tbl, result, value)
    if not table.find(tbl, value) and string.len(value) <= 2 then
        table.insert(result, value)
    end
end

local function filterStringTable(tbl)
    local result = {}

    for i, value in pairs(tbl) do
        addFilteredValue(tbl, result, value)
    end

    return result
end

local input = {"abcdef", "abcd", "abcd", "hello", "world"}
local output = filterStringTable(input)
print(input)
print(output)

It doesn’t work and I’m not sure why. I’ve simplified my own code down to just the string.len and here’s what it looks like:

local stringTable = {"a1", "a11", "a2", "a44", "a12"}

for _, stringValue in pairs(stringTable) do
	if string.len(stringValue) > 2 then
		print(stringValue) --prints only "a11" and "a44" 
		table.remove(stringTable, table.find(stringTable, table.find(stringTable, stringValue)))
	end
end

print(stringTable) --prints "a1", "a11", "a2"

Firstly the if statement itself isn’t working properly because it didn’t print “a12”.
Secondly, despite the loop essentially removing “a11”, it still shows up in the table.

Why might this be happening?

Actually, this is because of the table.remove.
The process goes like this:
Check index 1 (a1) => fine
Check index 2 (a11) => fine
Check index 3 (a2) => fine
Check index 4 (a44) => kill - But here, index four is kicked out and “a12” becomes index 4.
Since index 4 was already checked, it does not bother to check the new index 4.

You’d be better off adding the correct values to a separate table instead of table.removeing the bad ones.

1 Like