Jump to content

Module:table/setNested

From Wiktionary, the free dictionary

local error = error
local select = select

--[==[
Given a table, value and an arbitrary number of keys, will successively access subtables using each key in turn, and sets the value at the final key. For example, if {t} is { {} }, {export.setNested(t, "foo", 1, 2, 3)} will modify {t} to { {[1] = {[2] = {[3] = "foo"} } } }.

If no subtable exists for a given key value, one will be created, but the function will throw an error if a non-table value is found at an intermediary key.

Note: the parameter order (table, value, keys) differs from functions like rawset, because the number of keys can be arbitrary. This is to avoid situations where an additional argument must be appended to arbitrary lists of variables, which can be awkward and error-prone: for example, when handling variable arguments ({...}) or function return values.]==]
return function(...)
	local n = select("#", ...)
	if n < 3 then
		error("Must provide a table, value and at least one key.")
	end
	local t, v, k = ...
	for i = 4, n do
		local next_t = t[k]
		if next_t == nil then
			-- If there's no next table while setting nil, there's nothing more
			-- to do.
			if v == nil then
				return
			end
			next_t = {}
			t[k] = next_t
		end
		t, k = next_t, select(i, ...)
	end
	t[k] = v
end