Reputation: 3
Basically, scan the entire table for values of type say booleans for example and change them into a string, must work for inner tables and dictionaries...
local Table = {
String = "abc",
Number = 123,
Boolean = true,
InnerTable = {
Boolean2 = false,
InnerInnerTable = {
Boolean3 = true,
InnerInnerInnerTable = {
-- And so on...
}
}
}
}
In this example I want to change every boolean in the table to a string like "true" but without knowing what the table looks like, what I need is a function for any table parsed to be edited (dictionary or not). I couldn't accomplish this with a for loop or custom recursive functions so I need help.
Upvotes: 0
Views: 58
Reputation: 11171
What you need is a simple traversal of the table structure which maps booleans to strings. This can be implemented recursively as follows:
local function deep_bool_to_string(tab)
for k, v in pairs(tab) do
if type(v) == "boolean" then
tab[k] = tostring(v)
elseif type(v) == "table" then
deep_bool_to_string(v)
end
end
end
Usage in your example: deep_bool_to_string(Table)
. Mutates Table
.
Note that this only recursively dives into values, not keys of tables, as the latter isn't well defined: Should {["true"] = 1, [true] = 2}
become {["true"] = 1}
or {["true"] = 2}
?
In its current form, this function has two limitations:
(1) can be fixed by keeping track of already converted tables:
local deep_bool_to_string = function(tab)
local seen = {} -- "Set" of seen tables
local function convert(t)
seen[t] = true
for k, v in pairs(t) do
if type(v) == "boolean" then
t[k] = tostring(v)
elseif type(v) == "table" and not seen[v] then
convert(v)
end
end
end
convert(tab)
end
(2) can be fixed by implementing the traversal using a table-based "stack":
local deep_bool_to_string = function(tab)
local seen = {[tab] = true} -- "Set" of seen tables
local to_convert = {tab} -- "Stack" of tables to convert
repeat
local t = table.remove(to_convert) -- "pop" from stack
for k, v in pairs(t) do
if type(v) == "boolean" then
t[k] = tostring(v)
elseif type(v) == "table" and not seen[v] then -- new table found?
seen[v] = true
table.insert(to_convert, v) -- "push" on stack
end
end
until #to_convert == 0
end
All these are implementations of depth-first traversals, since they are usually more convenient to write (and more efficient) than breath-first traversals since they use a stack rather than a queue.
Upvotes: 3